In fact, it is not clear what you are asking. This may be one of several things. First, there would be simple combinations of different elements in the list. Scala offers this using the combinations() method from collections. If the elements are different, the behavior is exactly what you expect from the classic definition of "combinations." For n-element combinations of p elements, there will be p! / N! (Pn)! output combinations.
If there are duplicate elements in the list, Scala will generate combinations with the element appearing more than once in the combinations. But there are only different possible combinations, and the element may be replicated as many times as there is at the input. It generates only a set of possible combinations, therefore repeating elements, but not repeating combinations. I'm not sure there is an iterator at the heart of this for the actual Set .
Now what you really mean, if I understand correctly, are combinations from a given set of different p elements, where an element can appear repeatedly n times in a combination.
Well, let's go back a bit to generate combinations when elements are repeated at the input, and you want to see repeating combinations in the output, the way to do this is simply to generate it using “brute force” using n nested loops. Note that in reality there is nothing rude, it is just a natural number of combinations, really, which is O (p ^ n) for small n, and you can not do anything about it. You must be careful to choose these values correctly, for example:
val a = List(1,1,2,3,4) def comb = for (i <- 0 until a.size - 1; j <- i+1 until a.size) yield (a(i), a(j))
resulting in
scala> comb res55: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,1), (1,2), (1,3), (1,4), (1,2), (1,3), (1,4), (2,3), (2,4), (3,4))
This generates combinations of these duplicate values in a, first creating intermediate combinations 0 until a.size as (i, j) ...
Now, to create "combinations with repetitions", you just need to change the indices as follows:
val a = List('A','B','C') def comb = for (i <- 0 until a.size; j <- i until a.size) yield (a(i), a(j))
will create
List((A,A), (A,B), (A,C), (B,B), (B,C), (C,C))
But I'm not sure what the best way to generalize this to larger combinations.
Now I close what I was looking for when I found this post: a function to create combinations from input containing duplicate elements, with intermediate indices generated by combinations() . It's nice that this method creates a list instead of a tuple, so this means that we can really solve the problem using the "map card", which I'm not sure what anyone else suggested here, but it is pretty elegant and will make your love of FP and Scala grow a little more after you see her!
def comb[N](p:Seq[N], n:Int) = (0 until p.size).combinations(n) map { _ map p }
leads to
scala> val a = List('A','A','B','C') scala> comb(a, 2).toList res60: List[scala.collection.immutable.IndexedSeq[Int]] = List(Vector(1, 1), Vector(1, 2), Vector(1, 3), Vector(1, 2), Vector(1, 3), Vector(2, 3))