list Scala 列表中的模式匹配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13057668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:54:49  来源:igfitidea点击:

Pattern matching on a list in Scala

listscalapattern-matching

提问by Soumya Simanta

I'm a little confused regarding pattern matching on a list in Scala.

我对 Scala 中列表上的模式匹配有点困惑。

For example.

例如。

    val simplelist: List[Char] = List('a', 'b', 'c', 'd')

    //> simplelist  : List[Char] = List(a, b, c, d)

    def simple_fun(list: List[Char]) = list match {
           case (x:Char) :: (y:List[Char]) => println(x)
           case _ => Nil
     }                                                 
   //> simple_fun: (list: List[Char])Any

   simple_fun(simplelist)                            

   //> a
   //| res0: Any = ()

This currently prints only one line of output. Should it not run/pattern match on each element of the List ?

这当前仅打印一行输出。它不应该在 List 的每个元素上运行/模式匹配吗?

EDIT: I fixed the compile errors and copied the output from the REPL.

编辑:我修复了编译错误并复制了 REPL 的输出。

回答by Russell

Unless you are repeatedly calling simple_funin some way, what you have there will pattern match the first element and nothing more. To get it to match the whole list, you can get simple_funto call itself recursively, like this:

除非您simple_fun以某种方式反复调用,否则您所拥有的将模式匹配第一个元素,仅此而已。为了让它匹配整个列表,你可以simple_fun递归地调用它自己,就像这样:

val simplelist: List[Char] = List('a', 'b', 'c', 'd')

def simple_fun(list: List[Char]): List[Nothing] = list match {
  case x :: xs => {
    println(x)
    simple_fun(xs)
  }
  case _ => Nil 
}

Note I've also left out some of the types as the Scala compiler can infer them, leaving you with less cluttered, more readable code.

注意我还省略了一些类型,因为 Scala 编译器可以推断它们,让您的代码不那么混乱,更易读。

As a small side-note, calling printlnrepeatedly inside the function like that is not particularly functional - as it is all about side effects. A more idiomatic approach would be to have the function construct a string describing the list, which is then output with a single call to println- so the side-effects are kept in a single well-defined place. Something like this would be one approach:

作为一个小的旁注,println像这样在函数内部重复调用并不是特别实用 - 因为它都是关于副作用的。一种更惯用的方法是让函数构造一个描述列表的字符串,然后通过一次调用输出该字符串println- 因此副作用被保存在一个明确定义的地方。这样的事情将是一种方法:

def simple_fun(list: List[Char]):String = list match {
  case x :: xs => x.toString + simple_fun(xs)
  case Nil => ""
}

println(simple_fun(simple_list))

回答by S.Dayneko

I would also like to mention that the case for lists can be divided not only the head and tail, as well as any N number of list elements:

我还要提一下,列表的情况不仅可以分为头部和尾部,也可以分为任意 N 个列表元素:

def anyFunction(list: List[Int]): Unit =
  list match {
        // ...methods that have already been shown
      case first :: second :: Nil  => println(s"List has only 2 elements: $first and $second")
      case first :: second :: tail => println(s"First: $first \nSecond: $second \nTail: $tail")
  }

Hope it will be useful to someone.

希望它对某人有用。

回答by Manoj Shah

I think the following should work:

我认为以下应该有效:

def flatten(l: List[_]): List[Any] = l match {
  case Nil => Nil
  case (head: List[_]) :: tail => flatten(head) ::: flatten(tail)
  case head :: tail => head :: flatten(tail)
}

The first line is a match for Nil, so if we don't find anything return nothing. The second line will identify List of Lists and recall the flatten method and flatten the list of lists.

第一行是 Nil 的匹配项,所以如果我们没有找到任何东西就什么也不返回。第二行将识别 List of Lists 并调用 flatten 方法并展平列表列表。