如何在忽略顺序的情况下生成集合的成对组合?

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

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

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))。所以我想 return Set((3, 1), (3, 2), (1, 2)).

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

有什么想法吗?

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

如果您不介意使用一组集合而不是一组元组,那很简单:

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

Scala 也有一个 combinations 方法,但它只在 Seq 上定义,而不是 Set。所以先把你的set变成Seq,下面给你一个Iterator[Seq[Int]]:

x.toSeq.combinations(2)

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