2010-09-01 3 views
19

En supposant:Existe-t-il une méthode API qui compare le contenu d'un Seq indépendamment de l'ordre?

val l1 = List(1,2,3) 
val l2 = List(2,3,1) 

Je veux une méthode qui confirme que l1 est égale à l2 (comme dans le même contenu, mais un ordre différent). Existe-t-il une méthode API sur List/Seq pour faire cela?

l1.sameElements(l2) 

ne fonctionne pas car il vérifie également l'ordre.

Je suis venu avec ce qui suit:

l1.foldLeft(l1.size == l2.size)(_ && l2.contains(_)) 

Y at-il plus succinct que le ci-dessus pour faire cette comparaison?

+0

http://stackoverflow.com/questions/2944617/use-example-of-scala-observableset-trait –

+0

Comment la question liée se rapporte-t-elle à cette question? – ssanj

+0

Les ensembles pourraient résoudre son problème, mais son commentaire à la réponse ci-dessous indique qu'il veut que les doublons soient aussi supportés, ainsi les ensembles ne fonctionneront pas. –

Répondre

27

Si ce que vous voulez est « ces listes contiennent les mêmes éléments, quel que soit l'ordre ou des répétitions »:

l1.toSet == l2.toSet

Si ce que vous voulez est « ces listes contiennent les mêmes éléments, et avec la même nombre de répétitions de chaque « :

l1.sorted == l2.sorted

Si ce que vous voulez est » ces listes contiennent les mêmes éléments et sont de la même taille, mais le nombre de répétitions d'une donnée élément peut différer entre les deux listes ":

l1.size == l2.size && l1.toSet == l2.toSet

+0

Je souhaite également prendre en charge les éléments en double. Donc Liste (1,2,3,3) ne devrait pas être égal (Liste (3,2,1)) – ssanj

+0

Ok, édité pour refléter cela :) –

+0

Liste (1,2,3,3) .sorted! = Liste (3,2,1) – ssanj

9

Alors que

l1.sorted == l2.sorted 

est correct, ses performances d'exécution est O (n log n), en raison du tri. Pour les grandes listes, vous êtes probablement mieux avec

l1.groupBy(identity) == l2.groupBy(identity) 

qui devrait être O (n), en supposant une mise en œuvre correcte de groupBy.

+0

Dans Scala, je ne pense pas que la solution groupBy fonctionnera car les valeurs de la carte seront des tableaux, et ceux-ci seront comparés en utilisant l'égalité de référence. 'l1.groupBy (identité) .mapValues ​​(_. length) == ...' fonctionnerait bien. – csjacobs24