Supposons que j’ai une collection (utilisons un ensemble):
scala> val x = Set(1, 2, 3)
x: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
Je peux obtenir toutes les combinaisons par paires avec le code suivant:
scala> for {
| a <- x
| b <- x
| if a != b
| } yield (a, b)
res9: scala.collection.immutable.Set[(Int, Int)] = Set((3,1), (3,2), (1,3), (2,3), (1,2), (2,1))
Le problème est que je veux seulement obtenir toutes les combinaisons par paires où l’ordre est ignoré (donc la combinaison (1, 2)
est équivalent à (2, 1)
). Donc je voudrais revenir Set((3, 1), (3, 2), (1, 2))
.
Ne supposez pas que les éléments de la collection seront des entiers. Ils peuvent être de type arbitraire.
Des idées?
Edit: Python "s itertools.combinations
exécute la fonctionnalité exacte que je recherche. Je veux juste un moyen idiomatique de le faire dans Scala :)
Réponses:
11 pour la réponse № 1Scala a un combinations
méthode aussi, mais elle n’est définie que sur Seq
, ne pas Set
. Alors transformez votre poste en un Seq
d'abord, et ce qui suit vous donnera un Iterator[Seq[Int]]
:
x.toSeq.combinations(2)
Si vous voulez vraiment des n-uplets, ajoutez map {case Seq(a,b) => (a,b)}
à ce qui précède.
3 pour la réponse № 2
Si cela ne vous dérange pas d’avoir un ensemble d’ensembles au lieu d’un ensemble de tuples, c’est simple:
scala> val s3 = for {
| a <- x
| b <- x
| if(a != b)
| } yield ( Set(a,b))
s3: scala.collection.immutable.Set[scala.collection.immutable.Set[Int]] = Set(Set(1, 2), Set(1, 3), Set(2, 3))