将字符串与列表项匹配

时间:2016-12-21 17:00:29

标签: scala pattern-matching

我有一个列表和两个字符串:

def getElement(any: String): String = any match {
  case s :: rest if features.contains(s) => s + "= " + any
  case _ => // Nothing 
} 

我想将每个字符串与列表中的项匹配。

如果字符串的开头与列表项之一匹配,则打印匹配的列表项和字符串本身。

如果没有,则无需打印。

我有方法,我认为制作我需要的东西,但我无法编译它:

   scala> getElement(strOne)
          "one_five= one"

   scala> getElement(strTwo)

我想要以下内容:

plotOptions: {
    pie: {
        dataLabels: {
            distance: -30,
            format: '{point.percentage:.1f} %'
        }
    }
},

3 个答案:

答案 0 :(得分:3)

你不能只返回任何东西。您承诺您的方法会返回String,因此您必须返回一个。您可以返回Option[String](首选)或返回Unit并自行打印。此外,内置方法TraversableLike#find将完成部分工作。

def findFeature(str: String): Option[String] = features.find(_ startsWith str) map { value => s"$str=$value" }

为了获得打印行为:

findFeature(str) foreach println
// or redefine findFeature similarly

此外,您似乎误解了模式匹配:您不希望匹配字符串;你想匹配列表的元素字符串。这是一个使用模式匹配的版本:

def getElement(feature: String): Option[String] = {
  @tailrec def getElem0(feature: String, strs: List[String]): Option[String] = strs match {
    case s :: _ if s startsWith feature => Some(s"$feature=$s") // Matching case
    case _ :: rest => getElem0(feature, rest) // Not matched, but more to search
    case Nil => None // Empty list; failure
  }
  getElem0(feature, features)
}

答案 1 :(得分:2)

您的解决方案无法编译,因为::List方法,而s是字符串。此外,声明getElement返回String,因此它应返回任何输入的字符串。所以你不能在第二种情况下只返回“没有”。

这是另一种实现方式:

def printElement(any: String): Unit = features
  .find(s => any.startsWith(s)) // find matching (returns Option[String])
  .foreach(s => println(s + "= "+ any))  // print if found

printElement(strOne) // one= one_five
printElement(strTwo)

答案 2 :(得分:1)

简单的一行Scala代码

在列表中查找列表中第一部分的项目

features.find(_ == str.split("_")(0)).map { elem => s"$str= $elem"}.getOrElse("")

将上面一行放在函数中。

def getElement(str: String): String = features.find(_ == str.split("_")(0)).map { elem => s"$str= $elem"}.getOrElse("")

Scala REPL

scala>  val strOne = "one_five"
strOne: String = one_five

scala>  val str = "one_five"
str: String = one_five

scala> features.find(_ == str.split("_")(0)).getOrElse("")
res2: String = one

scala> features.find(_ == str.split("_")(0)).map(elem => s"$str= $elem").getOrElse("")
res3: String = one_five= one