J.D. J.D. - 3 months ago 15
Scala Question

Scala - collapse multiple Seqs

How can I transform a Seq[Seq[Int] such that each inner Seq contains the elements from the other two lists?

//Example:
val A = Seq(1, 2, 3)
val B = Seq(4, 5)
val C = Seq(6, 7, 8)
val input(A,B,C)
/**
* INPUT: [(1,2,3), (4,5), (6,7,8)]
* OUTPUT:[(1,4,6), (1,4,7), (1,4,8), (1,5,6), ..., (3,5,8)]
*/
def process(input: Seq[Seq[Int]]): Seq[Seq[Int]] = {
//unknown
}

Answer

If this is a homework assignment, I recommend you don't turn in the following (you might to reverse engineer a simpler solution involving recursion out of it I guess). However, if you are really just curious about this, there are some pretty neat tricks.

def convert[T](xs: Seq[Seq[T]]): Seq[Seq[T]] = 
  xs.foldLeft(Seq(Seq[T]()))((bs,ns) => for (b <- bs; n <- ns) yield b :+ n)

foldLeft emphasizes the fact that you will be starting from the left side of the input, working your way right one Seq at a time. Then, for every Seq you find, you take a cartesian product of sorts.

scala> convert(Seq(Seq(1,2,3), Seq(4,5), Seq(6,7,8)))
res: Seq[Seq[Int]] = List(List(1, 4, 6), List(1, 4, 7), List(1, 4, 8), 
List(1, 5, 6), List(1, 5, 7), List(1, 5, 8), List(2, 4, 6), List(2, 4, 7), 
List(2, 4, 8), List(2, 5, 6), List(2, 5, 7), List(2, 5, 8), List(3, 4, 6), 
List(3, 4, 7), List(3, 4, 8), List(3, 5, 6), List(3, 5, 7), List(3, 5, 8))
Comments