Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I yield pairwise combinations of a collection, ignoring order?

Let's assume I have a collection (let's use a set):

scala> val x = Set(1, 2, 3)
x: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

I can get all pairwise combinations with the following code:

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))

The problem is that I only want to get all pairwise combinations where order is ignored (so the combination (1, 2) is equivalent to (2, 1)). So I'd like to return Set((3, 1), (3, 2), (1, 2)).

Do not assume that the elements of the collection will be integers. They may be any arbitrary type.

Any ideas?

Edit: Python's itertools.combinations performs the exact functionality I'm looking for. I just want an idiomatic way to do it in Scala :)

like image 209
ccampo Avatar asked Feb 11 '15 01:02

ccampo


1 Answers

Scala has a combinations method too, but it's only defined on Seq, not Set. So turn your set into a Seq first, and the following will give you an Iterator[Seq[Int]]:

x.toSeq.combinations(2)

If you really want tuples, add map {case Seq(a,b) => (a,b)} to the above.

like image 79
Luigi Plinge Avatar answered Sep 18 '22 18:09

Luigi Plinge