Сопоставление шаблонов в списке в Scala
Я немного смущен относительно соответствия шаблонов в списке в Scala.
Например.
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 = ()
В настоящее время выводится только одна строка вывода. Должно ли оно не запускаться/соответствие шаблону для каждого элемента списка?
EDIT: Я исправил ошибки компиляции и скопировал вывод из REPL.
Ответы
Ответ 1
Если вы несколько раз вызываете 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
}
Примечание. Я также отказался от некоторых типов, поскольку компилятор Scala может их вывести, оставив вас с менее загроможденным и более читаемым кодом.
Как маленькая заметка, вызов 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))
Ответ 2
Я думаю, что следующее должно работать:
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)
}
Первая строка соответствует Nil, поэтому, если мы ничего не найдем, ничего не получим.
Вторая строка идентифицирует список списков и вызовет метод сглаживания и сгладит список списков.
Ответ 3
Также хотелось бы отметить, что падеж для списков можно разделить не только на голову и хвост, но и на любое количество элементов списка 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")
}
Надеюсь, это будет кому-то полезно.