A generic function for multiple generators to understand in Scala

Let's say I want to create all possible combinations of the letters "a" and "b". For combinations of length 2 used for understanding, this would be:

for {
   x <- Seq("a", "b") 
   y <- Seq("a", "b")
} yield x + y

      

And for combinations of length 3 it will be:

for {
   x <- Seq("a", "b") 
   y <- Seq("a", "b")
   z <- Seq("a", "b")
} yield x + y + z

      

Pretty similar. Is it possible to abstract this pattern and write a generic function? I can think of a signature like this:

def genericCombine[A,B](length: Int, elements: Seq[A])(reducer: Seq[A] => B): Seq[B]

      

How can I parameterize the number of generators used for understanding?

+3


source to share


1 answer


It's more like swapping permutations than combinations, and the recursive implementation is pretty straightforward:

def select(n: Int)(input: List[String]): List[String] =
  if (n == 1) input else for {
    c <- input
    s <- select(n - 1)(input)
  } yield c + s

      

Works as expected:



scala> select(2)(List("a", "b"))
res0: List[String] = List(aa, ab, ba, bb)

scala> select(3)(List("a", "b"))
res1: List[String] = List(aaa, aab, aba, abb, baa, bab, bba, bbb)

      

(Of course, you should check for invalid input in a real application.)

+4


source







All Articles