如何使用模式匹配在scala中获取一个nonEmpty列表?

时间:2016-01-04 05:36:36

标签: scala pattern-matching

我正在使用case x :: Nil => ...尝试确保列表为nonEmpty,但它只匹配单个元素列表。如何使用模式匹配获取非空列表?

已更新
对不起,似乎我失去了一些东西,有一个特殊的场景使用匹配内部,

object AccountResult{
  def unapply(account: AccountResult): Option[(String, List[String])] = ???
}

//ignore accountResult define please 
accountResult match {
  case AccountResult(_, x :: _) => ... 
}

如何匹配accountResult哪个List [String](x :: _)值不是Nil?然后获取匹配的List [String]值

4 个答案:

答案 0 :(得分:18)

不是仅指定带有Nil的空列表,而是指定可以是任何列表的内容,例如:

case x :: tail => ... // tail is a local variable just like x, holding the tail of the list

或简单地说:

case x :: _ => ...

如果你不关心或不会使用尾巴。

这些模式将匹配任何列表至少一个元素(而不是根据您现有模式的一个元素)。同样,模式:

case x :: y :: the_rest => ...

将匹配任何列表至少两个元素。

修改(回复您的评论):

您可以使用" @"分配案例模式中的变量。因此,对于您可能已经看过的(典型用法)示例:

case acc@AccountResult(_, x :: tail) => ... // do something with 'acc'

或者,根据您的评论匹配您正在寻找的用法:

case AccountResult(_, phone@(x :: tail)) => ... // do something with 'phone'

答案 1 :(得分:15)

要检查列表是否为空,您可以通过以下方式进行模式匹配:

list match {
   case Nil => false
   case _ => true
}

或者

list match {
  case Nil => false
  case x::xs => true  
}

答案 2 :(得分:3)

如果你只想将一个非空的列表分配给一个val,而不分割头部和尾部,你只需添加一个匹配空列表的case,另一个将列表分配给一个变量名,如下所示:

accountResult match {
  case List() => ??? // empty case
  case myAccountResult => ??? //myAccountResult will contain the whole non-empty list  
}

Nil也可以完成这项工作,匹配空列表

accountResult match {
  case Nil => ??? // empty case
  case myAccountResult => ??? //myAccountResult will contain the whole non-empty list  
}

答案 3 :(得分:2)

如果这是您经常使用的东西,您可以创建这样的自定义匹配器:

object NonEmpty { 
  def unapply(l: List[_]) = l.headOption.map(_ => l)
}

可以这样使用:

scala> List() match { case NonEmpty(l) => println(l) }
scala.MatchError: List() (of class scala.collection.immutable.Nil$)
  ... 33 elided

scala> List(43) match { case NonEmpty(l) => println(l) }
List(43)

scala> List(43, 32) match { case NonEmpty(l) => println(l) }
List(43, 32)