Wie finde ich in Scala einzigartige Gegenstände in der Liste?
77
Die effizienteste Methode zur Aufrechterhaltung der Ordnung wäre die Verwendung einer Set
als zusätzliche Datenstruktur:
def unique[A](ls: List[A]) = {
def loop(set: Set[A], ls: List[A]): List[A] = ls match {
case hd :: tail if set contains hd => loop(set, tail)
case hd :: tail => hd :: loop(set + hd, tail)
case Nil => Nil
}
loop(Set(), ls)
}
Wir können dies mit einer impliziten Konvertierung in eine schönere Syntax einschließen:
implicit def listToSyntax[A](ls: List[A]) = new {
def unique = unique(ls)
}
List(1, 1, 2, 3, 4, 5, 4).unique // => List(1, 2, 3, 4, 5)
In 2.8 ist es:
List(1,2,3,2,1).distinct // => List(1, 2, 3)
quelle
Rollen Sie Ihren eigenen Uniq-Filter mit Auftragserhaltung:
scala> val l = List(1,2,3,3,4,6,5,6) l: List[Int] = List(1, 2, 3, 3, 4, 6, 5, 6) scala> l.foldLeft(Nil: List[Int]) {(acc, next) => if (acc contains next) acc else next :: acc }.reverse res0: List[Int] = List(1, 2, 3, 4, 6, 5)
quelle
Wenn Sie sich auf den Rosetta-Code beziehen : Erstellen Sie eine Folge eindeutiger Elemente
val list = List(1,2,3,4,2,3,4,99) val l2 = list.removeDuplicates // l2: scala.List[scala.Int] = List(1,2,3,4,99)
Da
List
es unveränderlich ist, werden Sie die Initiale nichtList
durch Aufrufen ändernremoveDuplicates
Warnung: Wie in diesem Tweet (!) Erwähnt , bleibt die Reihenfolge nicht erhalten:
scala> val list = List(2,1,2,4,2,9,3) list: List[Int] = List(2, 1, 2, 4, 2, 9, 3) scala> val l2 = list.removeDuplicates l2: List[Int] = List(1, 4, 2, 9, 3)
Für a
Seq
sollte diese Methode in Scala2.8 gemäß Ticket 929 verfügbar sein .In der Zwischenzeit müssen Sie eine statische Ad-hoc-Methode wie die hier gezeigte definieren
quelle
toList
anscheinend an :) Oder verwenden Sie, wie von @Synesso vorgeschlagenfoldLeft
.Imho, alle Interpretationen der Frage sind falsch:
Angesichts dieser Liste:
val ili = List (1, 2, 3, 4, 4, 3, 1, 1, 4, 1)
Das einzige eindeutige Element in der Liste ist
2
. Die anderen Elemente sind nicht eindeutig.werde es finden.
quelle
list.filter { x => list.count(_ == x) == 1 }
quelle
Eine einfache Ad-hoc-Methode besteht darin, die Liste einem Set hinzuzufügen und von dort aus Folgendes zu verwenden:
val l = List(1,2,3,3,3,4,5,5,6,7,8,8,8,9,9) val s = Set() ++ x println(s)
Produziert:
> Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
Dies funktioniert für eine Seq (oder eine beliebige Iterable), ist jedoch in 2.8 nicht erforderlich, wo die removeDuplicates-Methode wahrscheinlich besser lesbar ist. Ich bin mir auch nicht sicher über die Laufzeitleistung im Vergleich zu einer durchdachten Konvertierung.
Beachten Sie auch die verlorene Bestellung.
quelle
list.toSet wird dies tun, da Set per Definition nur eindeutige Elemente enthält
quelle