Scalaでは集合を並び替えた順列(permutation)や、組み合わせ(combination, 重複を含まない)、冪集合(power set)などを手軽に生成できる。
scala> val l = List("A", "B", "C", "D")
l: List[java.lang.String] = List(A, B, C, D)
scala> l.permutations
res0: Iterator[List[java.lang.String]] = non-empty iterator
scala> res0.map(_.mkString(",")).mkString("\n")
res1: String =
A,B,C,D
A,B,D,C
A,C,B,D
A,C,D,B
A,D,B,C
A,D,C,B
B,A,C,D
B,A,D,C
B,C,A,D
B,C,D,A
B,D,A,C
B,D,C,A
C,A,B,D
C,A,D,B
C,B,A,D
C,B,D,A
C,D,A,B
C,D,B,A
D,A,B,C
D,A,C,B
D,B,A,C
D,B,C,A
D,C,A,B
D,C,B,A
scala> l.combinations(3)
res2: Iterator[List[java.lang.String]] = non-empty iterator
scala> res2.map(_.mkString(",")).mkString("\n")
res3: String =
A,B,C
A,B,D
A,C,D
B,C,D
冪集合(power set)を生成する関数はないが、冪集合を生成する関数は以下のように簡単に書ける。
scala> def powerSet[A](s:TraversableOnce[A]) =
| s.foldLeft(Set(Set.empty[A])) {
| (set, element) => set union (set map (_ + element))
| }
powerSet: [A](s: TraversableOnce[A])scala.collection.immutable.Set[scala.collection.immutable.Set[A]]
scala> powerSet(l.toSet)
res5: scala.collection.immutable.Set[scala.collection.immutable.Set[java.lang.String]] = Set(Set(A, D), Set(), Set(A, B), Set(B, C), Set(B), Set(A, B, C), Set(C), Set(A, B, C, D), Set(C, D), Set(A, C), Set(B, C, D), Set(A, C, D), Set(B, D), Set(A), Set(D), Set(A, B, D))
生成の様子を表示すると以下のようになる。
step 1. Set(Set())
step 2. Set(Set(), Set(A))
step 3. Set(Set(), Set(A), Set(B), Set(A, B))
step 4. Set(Set(), Set(A, B), Set(B, C), Set(B), Set(A, B, C), Set(C), Set(A, C), Set(A))
step 5. Set(Set(A, D), Set(), Set(A, B), Set(B, C), Set(B), Set(A, B, C), Set(C), Set(A, B, C, D), Set(C, D), Set(A, C), Set(B, C, D), Set(A, C, D), Set(B, D), Set(A), Set(D), Set(A, B, D))