it-swarm.com.de

Mustervergleich auf einer Liste in Scala

Ich bin ein wenig verwirrt in Bezug auf den Mustervergleich auf einer Liste in Scala.

Zum Beispiel.

    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 = ()

Dies druckt derzeit nur eine Ausgabezeile. Sollte es nicht für jedes Element der Liste ausgeführt werden/mit dem Muster übereinstimmen?

EDIT: Ich habe die Kompilierungsfehler behoben und die Ausgabe von der REPL kopiert.

10
Soumya Simanta

Wenn Sie simple_fun nicht wiederholt aufrufen, entspricht das dort vorhandene Muster dem ersten Element und nichts weiter. Damit es mit der gesamten Liste übereinstimmt, können Sie simple_fun so einstellen, dass es sich selbst rekursiv aufruft:

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 
}

Hinweis: Ich habe auch einige Typen weggelassen, da der Scala-Compiler sie herleiten kann, sodass Sie weniger überfüllten, besser lesbaren Code haben.

Als kleine Randnotiz ist das wiederholte Aufrufen von println in einer solchen Funktion nicht besonders funktional, da es sich nur um Nebenwirkungen handelt. Ein idiomatischerer Ansatz wäre, die Funktion eine Zeichenfolge erstellen zu lassen, die die Liste beschreibt, die dann mit einem einzigen Aufruf von println ausgegeben wird - damit die Nebenwirkungen an einem genau definierten Ort bleiben. So etwas wäre ein Ansatz:

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

println(simple_fun(simple_list))
23
Russell

Ich möchte auch erwähnen, dass die Groß- und Kleinschreibung für Listen nicht nur in Kopf und Schwanz, sondern auch in eine beliebige Anzahl von N Listenelementen unterteilt werden kann:

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")
  }

Hoffe, es wird jemandem nützlich sein.

2
S.Dayneko

Ich denke das folgende sollte funktionieren:

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)
}

Die erste Zeile entspricht Nil. Wenn wir also nichts finden, geben wir nichts zurück. Die zweite Zeile kennzeichnet die Liste der Listen und ruft die Methode zum Reduzieren und Reduzieren der Liste der Listen auf.

0
Manoj Shah