2012-10-24 11 views
8

Ich bin ein wenig verwirrt in Bezug auf Muster übereinstimmen auf einer Liste in Scala.Muster passen auf eine 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 Zeile der Ausgabe. Sollte es nicht auf jedem Element der Liste laufen/Muster übereinstimmen?

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

+0

Wie rufen Sie simple_fun – smk

+0

@SajitKunnumkal Ich habe meinen Beitrag bearbeitet, um Ihre Frage zu beantworten. –

Antwort

22

Es sei denn, Sie rufen wiederholt simple_fun in irgendeiner Weise, was Sie dort haben, wird Muster das erste Element und nichts mehr übereinstimmen. Um es um die ganze Liste übereinstimmen, können Sie simple_fun bekommen selbst rekursiv aufrufen, wie folgt aus:

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 habe ich auch links einige der Arten, wie die Scala-Compiler sie entnehmen kann, so dass Sie mit weniger überladener, besser lesbarer Code.

Als eine kleine Randnotiz, println wiederholt innerhalb der Funktion so zu rufen ist nicht besonders funktional - da es sich um Nebenwirkungen handelt. Ein idiomatischerer Ansatz wäre, dass die Funktion einen String konstruiert, der die Liste beschreibt, die dann mit einem einzigen Aufruf an println ausgegeben wird - so werden die Nebenwirkungen an einem einzigen klar definierten Ort gehalten. So etwas wie dies 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)) 
+1

Danke. Daher wird die Musterübereinstimmung nur einmal aufgerufen und nicht für jedes Element in der Liste. Außerdem musste ich einen Rückgabetyp (Unit) explizit zu simple_fun hinzufügen, um es rekursiv aufrufen zu können. –

+0

Kein Problem! Ja, ich realisierte, dass (über rekursive Funktionen, die einen Rückgabetyp benötigen), während der Antwort ein bisschen Klärung hinzugefügt wurde, um sie zu korrigieren. Hast du den Scala-Kurs auf coursera.org verfolgt? – Russell

+0

Ich verstehe, dass println Nebenwirkungen erzeugt. Ich habe es nur für dieses einfache Beispiel hinzugefügt. Ich stimme zu, es sollte nicht Teil eines echten Codes sein, wenn man rein funktional sein will. –

-1

Ich denke, die folgenden Arbeiten:

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 ein Spiel für Nil ist, so dass, wenn wir etwas nicht nichts finden zurückzukehren. Die zweite Zeile identifiziert die Liste der Listen und ruft die Flattenmethode auf und reduziert die Liste der Listen.

+1

Diese Frage wurde beantwortet, und die Antwort wurde vor 4 Jahren angenommen. Nicht nur ist deine Antwort ein wenig zu spät zur Party, es verfehlt auch den Punkt. Die Frage bezog sich auf den einfachen Mustervergleich. In der Frage nach geschachtelten Listen ist nichts enthalten. – jwvh