Comment en Scala trouver des objets uniques dans List?
Réponses
Trop de publicités? Pour ce faire, le moyen le plus efficace de préserver les commandes consiste à utiliser une structure de données auxiliaire Set
:
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)
}
Nous pouvons envelopper cette syntaxe plus jolie en utilisant une conversion implicite:
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)
Si vous vous reportez au Rosetta Code: Créer une Séquence d'éléments uniques
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)
Depuis List
est immuable, de ne pas modifier la première List
en appelant removeDuplicates
Avertissement: comme mentionné par ce tweet(!), ce n'est pas de préserver l'ordre:
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)
Pour un Seq
, cette méthode devrait être disponible dans Scala2.8, en fonction de billet 929.
Dans l'intervalle, vous devez définir un ad-hoc méthode statique que l' on voit ici
Une simple méthode ad-hoc consiste simplement à ajouter la liste à un ensemble et à l'utiliser à partir de là:
val l = List(1,2,3,3,3,4,5,5,6,7,8,8,8,9,9)
val s = Set() ++ x
println(s)
Produit:
> Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
Cela fonctionne pour un Seq (ou tout autre Iterable), mais n'est pas nécessaire en 2.8, où la méthode removeDuplicates sera probablement plus lisible. En outre, je ne suis pas sûr des performances d'exécution par rapport à une conversion plus réfléchie.
Notez également la commande perdue.