I have a scala list of following structure:
val list = List(
List(a1,a2,a3,a4,a5),
List(b1,b2,b3,b4,b5),
List(c1,c2,c3,c4,c5)
)
From this list, I want to generate a list which would look like:
List(
List(a1,b1,c1),
List(a2,b2,c2),
List(a3,b3,c3),
List(a4,b4,c4),
List(a5,b5,c5)
)
How do I achieve this in scala ?
If you have a fixed number of such lists, you can use zipped
to zip them together (into tuples). As in your example:
scala> (List(a1,a2,a3,a4), List(b1,b2,b3,b4), List(c1,c2,c3,c4)).zipped.toList
List((a1,b1,c1),(a2,b2,c2),(a3,b3,c3),(a4,b4,c4))
If you really want the full power of what you have above, it is just the transpose
of your list of lists:
scala> List(List(a1,a2,a3,a4), List(b1,b2,b3,b4), List(c1,c2,c3,c4)).transpose
List(List(a1,b1,c1),List(a2,b2,c2),List(a3,b3,c3),List(a4,b4,c4))
Here is a manual implementation of the library function.
object CustomZipTest extends App{
val list1: List[String] = List("a", "1", "w")
val list2: List[String] = List("b", "2", "x")
val list3: List[String] = List("c", "3", "y")
val list4: List[String] = List("d", "4", "z")
def customZip[T](list: List[T] *): List[List[T]] = {
def stripOneLevel(list: Seq[List[T]]): (Seq[List[T]], List[T]) = {
list.foldRight(Seq(): Seq[List[T]], List(): List[T]){ (e, acc) =>
if (e.size == 1) (acc._1, e.head +: acc._2)
else (e.tail +: acc._1, e.head +: acc._2)
}
}
def strip(list: Seq[List[T]], acc: List[List[T]]): List[List[T]] = {
list match {
case Nil => acc
case x+:xs =>
val stripped = stripOneLevel(list)
strip(stripped._1, stripped._2 +: acc)
}
}
strip(list, List()).reverse
}
println(customZip(list1, list2, list3, list4))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With