Pattern 将 Seq 与 Range 匹配
Pattern match a Seq with Range
考虑一段代码:
def foo(xs: Seq[Int]) = xs match {
case Nil => "empty list"
case head :: Nil => "one element list"
case head :: tail => s"head is $head and tail is $tail"
}
val x1 = Seq(1,2,3)
println(foo(x1))
val x2 = Seq()
println(foo(x2))
val x3 = Seq(1)
println(foo(x3))
val problem = 1 to 10
println(foo(problem))
当我们尝试匹配 foo(problem)
中的范围时出现问题。
scala.MatchError: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (of class scala.collection.immutable.Range$Inclusive)
.
使用 val problem = (1 to 10).toSeq
将 Range 转换为 Seq 是无用的,因为 toSeq
方法只是 returns Range 本身:
override def toSeq = this
.
可以使用解决方法:
val problem = (1 to 10).toList.toSeq
,
但这并不是我见过的最漂亮的东西。
将 Range 匹配到 [head:tail] 模式的正确方法是什么?
您可以使用 +:
运算符。就像 ::
,除了它不仅适用于 List,还适用于任何 Seq。
def foo(xs: Seq[Int]) = xs match {
case Seq() => "empty list"
case head +: Seq() => "one element list"
case head +: tail => s"head is $head and tail is $tail"
}
或者,更好的是,只在 Seq
提取器上进行模式匹配:
def foo(xs: Seq[Int]) = xs match {
case Seq() => "empty list"
case Seq(head) => "one element list"
case Seq(head, tail @ _*) => s"head is $head and tail is $tail"
}
考虑一段代码:
def foo(xs: Seq[Int]) = xs match {
case Nil => "empty list"
case head :: Nil => "one element list"
case head :: tail => s"head is $head and tail is $tail"
}
val x1 = Seq(1,2,3)
println(foo(x1))
val x2 = Seq()
println(foo(x2))
val x3 = Seq(1)
println(foo(x3))
val problem = 1 to 10
println(foo(problem))
当我们尝试匹配 foo(problem)
中的范围时出现问题。
scala.MatchError: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (of class scala.collection.immutable.Range$Inclusive)
.
使用 val problem = (1 to 10).toSeq
将 Range 转换为 Seq 是无用的,因为 toSeq
方法只是 returns Range 本身:
override def toSeq = this
.
可以使用解决方法:
val problem = (1 to 10).toList.toSeq
,
但这并不是我见过的最漂亮的东西。
将 Range 匹配到 [head:tail] 模式的正确方法是什么?
您可以使用 +:
运算符。就像 ::
,除了它不仅适用于 List,还适用于任何 Seq。
def foo(xs: Seq[Int]) = xs match {
case Seq() => "empty list"
case head +: Seq() => "one element list"
case head +: tail => s"head is $head and tail is $tail"
}
或者,更好的是,只在 Seq
提取器上进行模式匹配:
def foo(xs: Seq[Int]) = xs match {
case Seq() => "empty list"
case Seq(head) => "one element list"
case Seq(head, tail @ _*) => s"head is $head and tail is $tail"
}