如何在Scala中模式匹配数组?

del*_*ber 66 scala

我的方法定义如下所示

def processLine(tokens: Array[String]) = tokens match { // ...
Run Code Online (Sandbox Code Playgroud)

假设我想知道第二个字符串是否为空白

case "" == tokens(1) => println("empty")
Run Code Online (Sandbox Code Playgroud)

不编译.我该怎么做呢?

Rue*_*ler 106

如果要在数组上进行模式匹配以确定第二个元素是否为空字符串,则可以执行以下操作:

def processLine(tokens: Array[String]) = tokens match {
  case Array(_, "", _*) => "second is empty"
  case _ => "default"
}
Run Code Online (Sandbox Code Playgroud)

_*结合到任何数量的元件,包括无.这与列表中的以下匹配类似,可能更为人所知:

def processLine(tokens: List[String]) = tokens match {
  case _ :: "" :: _ => "second is empty"
  case _ => "default"
}
Run Code Online (Sandbox Code Playgroud)

  • @devssh`尾@_*` (3认同)
  • 如何图案匹配尾巴?它留为_ * (2认同)

par*_*tic 7

模式匹配可能不是您的示例的正确选择.你可以简单地做:

if( tokens(1) == "" ) {
  println("empty")
}
Run Code Online (Sandbox Code Playgroud)

模式匹配对于以下情况更为适用:

for( t <- tokens ) t match {
   case "" => println( "Empty" )
   case s => println( "Value: " + s )
}
Run Code Online (Sandbox Code Playgroud)

为每个令牌打印一些东西.

编辑:如果要检查是否存在任何空字符串的标记,您还可以尝试:

if( tokens.exists( _ == "" ) ) {
  println("Found empty token")
}
Run Code Online (Sandbox Code Playgroud)

  • @deltanovember`println`是使你的代码程序化的原因.你明显的困惑源于这样一个事实:在Scala中,`if`块是表达式而不是语句(即它们返回一个值,因此功能完备).使用"if"表达式而不是模式匹配没有任何固有的程序性. (6认同)
  • 这绝对有效,但似乎是做事的程序方式。我试图从功能的角度思考 (2认同)

syn*_*pse 6

更酷的是你可以使用别名来匹配类似的_*东西

val lines: List[String] = List("Alice Bob Carol", "Bob Carol", "Carol Diane Alice")

lines foreach { line =>
  line split "\\s+" match {
    case Array(userName, friends@_*) => { /* Process user and his friends */ }
  }
}
Run Code Online (Sandbox Code Playgroud)