80 votes

Comment en Scala trouver des objets uniques dans la liste

Comment en Scala trouver des objets uniques dans List?

220voto

jamesqiu Points 821

En 2.8, c'est:

 List(1,2,3,2,1).distinct  // => List(1, 2, 3)
 

24voto

Daniel Spiewak Points 30706

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)
 

14voto

Synesso Points 8865

Roulez votre propre filtre uniq avec rétention d’ordre:

 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)
 

10voto

VonC Points 414372

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

2voto

Mitch Blevins Points 7646

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X