2016-07-30 23 views
0

Ich habe eine ListeWie entfernen Sie jede Instanz einer Liste aus einer anderen Liste?

val l = List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2) 

und ich möchte jede Instanz einer bestimmten Sequenz entfernen, wie beispielsweise (2,3)

So ist die gewünschte Ausgabe ist ...

List(1,2,6,4,4,2,1,3,6,3,2) 

Was ist der einfachste/am meisten idiomatische Art, dies in Scala zu erreichen?

Ich habe versucht, dies zu tun, so weit ..

l.sliding(2).filter{ _!=List(2,3) } 

aber dann kann ich nicht herausfinden, von dort aus zu gehen, die mich gemacht frage mich, ob ich auf dem richtigen Weg bin.

+1

Ich bin nicht einmal sicher, dass diese Frage gut definiert ist. Was mache ich wenn ich 'List (1,2,1,2,1)' habe und die Sequenz '1,2,1' entfernen will. Erhalte ich "List (1,2)" oder "List (2,1)"? – Alec

+0

@ cricket_007 Ich habe meine Frage aktualisiert @Alec Im Allgemeinen sind Sie richtig. In diesem speziellen Fall müsste ich das Entfernen von links beginnen und nach rechts gehen, so würde das Ergebnis in Ihrem Beispiel 'List (2,1)' sein. –

+0

Danke für die Bearbeitung, aber wo willst du hin? von dort? Funktioniert das nicht für dich? –

Antwort

1

Sie können rekursiv durch die Liste durchlaufen, verbrauchenden Elemente aus dem Kopf der Liste einen nach dem anderen und den gewünscht diejenigen in eine Ergebnisliste ansammeln, während Verwerfen die übereinstimmende unerwünschte Sequenz. Ein einfaches tail-rekursive Beispiel könnte wie folgt funktionieren:

@annotation.tailrec 
def filterList[A](list: List[A], acc: List[A] = Nil): List[A] = list match { 
    case 2 :: 3 :: tail => filterList(tail, acc) 
    case head :: tail => filterList(tail, head :: acc) 
    case Nil => acc.reverse 
} 

scala> val l = List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2) 
scala> filterList(l) 
res0: List[Int] = List(1, 2, 6, 4, 4, 2, 1, 3, 6, 3, 2) 

Oder allgemeiner, Sie startsWith zu prüfen, ob die aktuelle Iteration von List beginnt mit der Sequenz verwenden, können Sie entfernen möchten.

@annotation.tailrec 
def filterList[A](list: List[A], subList: List[A], acc: List[A] = Nil): List[A] = list match { 
    case l if(list startsWith subList) => filterList(l.drop(subList.length), subList, acc) 
    case head :: tail => filterList(tail, subList, head :: acc) 
    case Nil => acc.reverse 
} 

scala> filterList(l, List(2, 3)) 
res4: List[Int] = List(1, 2, 6, 4, 4, 2, 1, 3, 6, 3, 2) 

Wenn die Leistung ein Problem ist, können Sie die acc wandelbar machen.

+0

Danke für diese Antwort m-z, ich brauchte diesen rekursiven Schwanz, um den Stack auf meinem Anwendungsfall nicht zu zerstören. –

1
def stripFrom[A](lst: List[A], x: List[A]): List[A] = 
    if (lst.containsSlice(x) && x.length > 0) 
    stripFrom(lst.patch(lst.indexOfSlice(x), List(), x.length), x) 
    else lst 

Proof-of-Concept:

scala> stripFrom(List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2), List(2,3)) 
res3: List[Int] = List(1, 2, 6, 4, 4, 2, 1, 3, 6, 3, 2) 

scala> stripFrom(List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2), List(4,2)) 
res4: List[Int] = List(1, 2, 3, 2, 6, 3, 1, 3, 6, 3, 2) 

scala> stripFrom(List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2), List(4,2,3,4)) 
res5: List[Int] = List(1, 2, 3, 2, 6, 2, 1, 3, 6, 3, 2) 

scala> stripFrom(List(1,2,3,2,6,4,2,3,4,2,1,3,6,3,2), List(2)) 
res6: List[Int] = List(1, 3, 6, 4, 3, 4, 1, 3, 6, 3) 
+0

Beachten Sie, dass dies sehr langsam wird, wenn viele Instanzen von 'x' aus' lst' entfernt werden müssen, da die Liste viele Male durchlaufen werden muss, um dies in die Nähe von O (n^2) zu bringen. . –

Verwandte Themen