如何产生一个集合的成对组合,忽略顺序?

时间:2015-02-11 01:36:18

标签: scala functional-programming

我们假设我有一个集合(让我们使用一套):

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

我可以使用以下代码获得所有成对组合:

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

问题在于我只想获得忽略顺序的所有成对组合(因此组合(1, 2)等同于(2, 1))。所以我想返回Set((3, 1), (3, 2), (1, 2))

不要假设集合的元素是整数。它们可以是任意类型。

有什么想法吗?

编辑:Python的itertools.combinations执行我正在寻找的确切功能。我只想在Scala中使用惯用的方法:)

2 个答案:

答案 0 :(得分:13)

Scala也有combinations方法,但它仅在Seq上定义,而不是Set。首先将您的设置转换为Seq,然后以下内容将为您提供Iterator[Seq[Int]]

x.toSeq.combinations(2)

如果你真的想要元组,请在上面添加map {case Seq(a,b) => (a,b)}

答案 1 :(得分:3)

如果您不介意拥有一组集而不是一组元组,那么很容易:

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