[英]Match to the n-th element of a list in Scala
What is the best Scala idiom for matching a value to the n-th element of a list? 将值与列表的第n个元素匹配的最佳Scala习惯用法是什么?
The naive approach obviously doesn't work: 天真的方法显然不起作用:
scala> val list = List(5,6,7)
list: List[Int] = List(5, 6, 7)
scala> val x = 7
x: Int = 7
scala> x match { case list(2) => true; case _ => false }
<console>:10: error: value list is not a case class constructor, nor does it have an unapply/unapplySeq method
x match { case list(2) => true; case _ => false }
To clarify- this question is not about how to compare a value to the n-th element of a list - it is specifically about whether it can be done using matching. 为了澄清 - 这个问题不是关于如何将值与列表的第n个元素进行比较 - 具体是关于是否可以使用匹配来完成。
Behold, the power of instance extractors! 看哪,实例提取器的力量! (the
Regex
class in the stdlib works similarly) (stdlib中的
Regex
类的工作方式类似)
case class Nth[A](which: Int) {
def unapply(in: List[A]): Option[A] = if (in.size >= which+1) Some(in(which)) else None
}
val second = Nth[Int](1)
List(2,4,6) match {
case second(4) => println("yep!")
case x => println("nope!")
}
you can match the list: 你可以匹配清单:
def l(X : Int) = list match {
case _ :: _ :: X :: _ => true
case _ => false
}
scala> l(4)
res13: Boolean = false
scala> l(7)
res14: Boolean = true
Well, List
doesn't define such an extractor, but you can: 好吧,
List
没有定义这样的提取器,但你可以:
scala> class IndexOf[T](seq: Seq[T]) {
| def unapply(x: T) = seq find (x ==) map (seq indexOf _)
| }
defined class IndexOf
scala> val list = List(5,6,7)
list: List[Int] = List(5, 6, 7)
scala> val listndx = new IndexOf(list)
listndx: IndexOf[Int] = IndexOf@35cd1217
scala> val x = 7
x: Int = 7
scala> x match { case listndx(2) => true; case _ => false }
res2: Boolean = true
Note that this will always return the first match. 请注意,这将始终返回第一个匹配项。 Scala pattern matching does not work like Prolog -- it doesn't feed
2
and see if that can be true somehow. Scala模式匹配不像Prolog那样工作 - 它不会提供
2
并查看是否可以某种方式为真。
Not directly. 不是直接的。 However, one of these may do:
但是,其中一个可能会:
x match { case _ if x == list(2) => true; case _ => false }
or 要么
val listElem = list(2)
x match { case `listElem` => true; case _ => false }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.