Pattern match a Seq with Range

戏子无情 提交于 2019-12-20 05:54:04

问题


Consider a piece of code:

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))

A problem occurs, when we try to match a Range in foo(problem).

scala.MatchError: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) (of class scala.collection.immutable.Range$Inclusive).

Converting Range to Seq with val problem = (1 to 10).toSeq is useless, as the toSeq method just returns the Range itself:

override def toSeq = this.

A workaround can be used:

val problem = (1 to 10).toList.toSeq,

but it's not exactly the prettiest thing I've seen.

What is the proper way to match a Range to [head:tail] pattern?


回答1:


You can use the +: operator. It's like ::, except instead of only being for List, it works on any 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"
}

Or, even better, just pattern match on the Seq extractor:

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"
}


来源:https://stackoverflow.com/questions/28989220/pattern-match-a-seq-with-range

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!