Рефакторинг случая совпадения Scala для списка строк - PullRequest
0 голосов
/ 06 мая 2018

У меня есть следующее:

def myFunc(str: String): Something => {

    str match {
        case "a" | "a1" | "abc" | "qwe" | "23rs" => Something
        case _ => None
    }    
}

Список строк может быть очень длинным, я хотел бы извлечь его из функции. Я не знаю, что искать, так как делаю

def isSomething(str: String): Boolean => {
  List("a","a1","abc","qwe","23rs").contains(str)
}

но case isSomething => Something не работает

Ответы [ 4 ]

0 голосов
/ 07 мая 2018

Большинство других ответов, кажется, охватывают исправление использования опции или уход от сопоставления с образцом (простое использование охранников на самом деле не сопоставление с образцом, IMO)

Думаю, вы спрашиваете об экстракторах. Если это так, это может быть ближе к тому, что вы хотите:

  case class Something(str: String)

  // define an extractor to match our list of Strings

  object MatchList {
    def unapply(str: String) = {
      str match {
        case "a" | "a1" | "abc" | "qwe" | "23rs" => Some(str)
        case _                                   => None
      }
    }
    }

    def myFunc(str: String): Option[Something] = {

      // use our new extractor (and fix up the use of Option while we're at it)    
      str match {
        case MatchList(str) => Some(Something(str))
        case _              => None
      }
    }

// Couple of test cases...
    myFunc("a")    // Some(Something(a))
    myFunc("b")    // None
0 голосов
/ 06 мая 2018

Ваш str является строкой, следовательно, не будет соответствовать isSomething, который имеет логический тип. Другая проблема с вашим примером кода заключается в том, что None имеет тип Option, поэтому было бы более целесообразно, чтобы ваши совпадения возвращали тот же тип. Вот один подход, использующий guard для условия contains:

val list = List("a", "a1", "abc", "qwe", "23rs")

val s = "abc"

s match {
  case s if list contains s => Some(s)
  case _ => None
}
// res1: Option[String] = Some(abc)
0 голосов
/ 06 мая 2018

Вы можете сделать что-то вроде ниже

val list = List("a", "a1", "abc", "qwe", "23rs")

def myFunc(str: String): Option[String] = {
  list.contains(str) match {
    case true => ??? //calling something function should return Some
    case false => None
  }
}

Option[String] можно изменить в зависимости от типа возвращаемого вами значения, но None предполагает, что истинный регистр должен возвращать тип Option. Таким образом, String можно изменить на желаемый тип данных

0 голосов
/ 06 мая 2018

Сначала вы использовали неправильный оператор => при определении функции.

scala> def isSomething(str: String): Boolean = {
     |   List("a","a1","abc","qwe","23rs").contains(str)
     | }
isSomething: (str: String)Boolean

scala> def myFunc(str: String): String = {
     | 
     | str match {
     | case str if(isSomething(str)) => "Something"
     | case _ => "None"
     | }
     | }
myFunc: (str: String)String

scala> myFunc("a")
res9: String = Something

Я не знаю, что это такое, поэтому я воспринял это как строку. Вы можете изменить его в соответствии с вашим вариантом использования. Надеюсь, это поможет.

...