模式匹配列表中的元素在Scala中

时间:2015-03-26 07:33:42

标签: list scala pattern-matching

我想按照以下方式进行:

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

你能解释一下原因吗?

5 个答案:

答案 0 :(得分:2)

要匹配等于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
}

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

这可能有效,

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

答案 4 :(得分:1)

您的方法不起作用,因为模式匹配中的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)