2015-02-11 56 views
4

假設我有一個集合(讓我們用一組):如何產生集合的成對組合,忽略順序?

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執行我正在尋找的確切功能。我只想得到一個地道的方式做到這一點斯卡拉:)

回答

11

Scala有一個combinations方法但它只在Seq而不是Set上定義。所以,把你套入一個Seq第一了,下面會給你一個Iterator[Seq[Int]]

x.toSeq.combinations(2) 

如果你真的想要的元組,添加map {case Seq(a,b) => (a,b)}以上。

+0

剛剛在API文檔中發現此方法之前,我再次在此處檢查。這是它。謝謝! – ccampo 2015-02-11 03:25:41

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

然後你可以使用'map {set => set.toList(0) - > set.toList(1)}'或類似的東西映射到元組 – 2015-02-11 03:25:07

+0

這是一個有趣的方法。謝謝! – ccampo 2015-02-11 03:26:49