Zec*_*tes 56 collections scala pattern-matching
我有以下代码,它们对List中的每个元素进行递归操作
def doMatch(list: List[Int]): Unit = list match {
case last :: Nil => println("Final element.")
case head :: tail => println("Recursing..."); doMatch(tail)
}
Run Code Online (Sandbox Code Playgroud)
现在,忽略通过filter()和foreach()可以使用此功能,这可以正常工作.但是,如果我尝试将其更改为接受任何Seq [Int],我会遇到问题:
以下是我认为代码的外观,除非它不起作用:
def doMatch(seq: Seq[Int]): Unit = seq match {
case last +: Seq() => println("Final element.")
case head +: tail => println("Recursing..."); doMatch(tail)
}
Run Code Online (Sandbox Code Playgroud)
编辑:这么多好的答案!我接受了agilesteel的答案,因为他是第一个注意到::在我的例子中不是运算符,而是一个案例类,因此差异.
Lan*_*dei 51
有点作弊,但在这里:
def doMatch(seq: Seq[Int]): Unit = seq match {
case Seq(x) => println("Final element " + x)
case Seq(x, xs@_*) => println("Recursing..." + x); doMatch(xs)
}
Run Code Online (Sandbox Code Playgroud)
不要问我为什么xs*不工作......
yak*_*ver 51
截至2012年3月的想法,这适用于2.10+:
def doMatch(seq: Seq[Int]): Unit = seq match {
case last +: Seq() => println("Final element.")
case head +: tail => println("Recursing..."); doMatch(tail)
} //> doMatch: (seq: Seq[Int])Unit
doMatch(List(1, 2)) //> Recursing...
//| Final element.
Run Code Online (Sandbox Code Playgroud)
更一般地,Seq在SeqExtractors中添加了两个不同的head/tail和init/last分解对象镜像append/prepend :
List(1, 2) match { case init :+ last => last } //> res0: Int = 2
List(1, 2) match { case head +: tail => tail } //> res1: List[Int] = List(2)
Vector(1, 2) match { case init :+ last => last } //> res2: Int = 2
Vector(1, 2) match { case head +: tail => tail } //> res3: scala.collection.immutable.Vector[Int] = Vector(2)
Run Code Online (Sandbox Code Playgroud)
dhg*_*dhg 24
您实际上可以定义一个对象,+:以便完全按照您的要求进行操作:
object +: {
def unapply[T](s: Seq[T]) =
if(s.nonEmpty)
Some(s.head, s.tail)
else
None
}
scala> val h +: t = Seq(1,2,3)
h: Int = 1
t: Seq[Int] = List(2, 3)
Run Code Online (Sandbox Code Playgroud)
然后您的代码完全按预期工作.
这是有效的,因为h +: t它等同于+:(h,t)用于模式匹配的时候.
| 归档时间: |
|
| 查看次数: |
35531 次 |
| 最近记录: |