使用模式匹配查找子列表

时间:2012-04-18 12:24:33

标签: scala

我需要使用模式匹配查找子列表,我该怎么做?

val list1 = List(2, 3)
val list2 = List(1, "2", list1, "r")
val list3 = list2 match {
      case // insert match statement here
      case _ => "failed"
}

assertEquals(list1, list3)

我无法更改给定的代码,我可能只在这里插入代码 case // insert match statement here 这是学校的任务(不是来自工作)

2 个答案:

答案 0 :(得分:4)

您不希望匹配,您想要查找

list2.find(_ == list1)

会为您提供Some(List(2, 3))(如果找不到,则为None)。为了准确匹配您的代码,您需要:

list2.find(_ == list1).getOrElse("failed")

虽然使用Option而不是可能的字符串是处理错误条件的更好方法。

如果你真的想要使用匹配,你必须递归地执行:

final def findOrFailed(xs: List[Any], what: Any): Any = xs match {
  case x :: rest => if (x == what) x else findOrFailed(rest,what)
  case _ => "failed"
}

(同样,我更喜欢一个选项,但我在这里给出了字符串版本。)

答案 1 :(得分:2)

你走了。第一个列表只需.find。由于您不清楚您正在寻找哪个子列表,我只假设第一个。否则,您必须调整用于查找调用的谓词。

val list1 = List(2, 3)
val list2 = List(1, "2", list1, "r")
val list3 = list2.find(_.isInstanceOf[List[_]]) match {
      case Some(listFound) => listFound
      case _ => "failed"
}

assertEquals(list1, list3) // true

另一个“解决方案”:

问题不够明确。正如雷克斯指出的那样,通过匹配声明,你不会走得太远。要仅满足上面的最小示例(可能是所有作业要求),您可以匹配确切的列表。即你可以硬编码你想要的列表的第三个元素。在这种情况下,你可以这样写:

case x :: y :: mylist :: rest => mylist

这使得接下来毫无意义,但解决了所需的断言,因此最好是使用::来构建列表。