Scala 中列表的模式匹配元素

Pattern match element of list in Scala

我正在尝试按如下方式进行:

def contains(x: Int, l: List[Int]) = l match { // this is just l.contains(x)
  case _ :: x :: _ => true
  case _ => false
}

不幸的是它不起作用

scala> contains(0, List(1, 2, 3))
res21: Boolean = true

scala> contains(1, List(1, 2, 3))
res22: Boolean = true

scala> contains(3, List(1, 2, 3))
res23: Boolean = true

你能解释一下为什么吗?

第一种情况匹配非空列表中的任何项目,注意,

scala> contains(123, List(1, 2, 3))
res1: Boolean = true

scala> contains(123, List())
res2: Boolean = false

匹配列表头项的递归方法可能有效。

首先,case节中的x是局部变量的别名。这不是 x 你传递给方法的。

其次,_ :: x :: _ 匹配任何包含两个或更多元素的列表。所以你所有的输出都是 true.

这可能有用,

  def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
    case _ :: x :: _  if(x == y)=> true
    case _ => false
  }

您的方法不起作用,因为模式匹配中的 x 绑定到第二个列表元素具有的任何值。它基本上是一个新变量。

替代S.K的答案

def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
  case _ :: x :: _  => x == y
  case _ => false
}

或者你也可以这样写

def contains[A](y: A, l: Seq[Int]) = (l.lift)(1).exists(_ == y)

要匹配等于 x 的数字,您可以将其放入反引号中:

def contains(x: Int, l: List[Int]) = l match {
  case _ :: `x` :: _ => true
  case _ => false
}

不幸的是 :: 匹配器只从列表中取出一个项目——第一个,所以这段代码只能找到 l 中的第二个项目:

scala> contains(1, List(1,2,3))
res2: Boolean = false

scala> contains(2, List(1,2,3))
res3: Boolean = true

scala> contains(3, List(1,2,3))
res4: Boolean = false

我相信,如果没有递归,您无法匹配列表中的任意项:

def contains(x: Int, l: List[Int]): Boolean = l match { // this is just l.contains(x)
  case `x` :: xs => true
  case _ :: xs => contains(x, xs)
  case _ => false
}