1

I have number of lists, how can I make a function which takes in lists and then return tuple. Currently I am doing it as:

val s1 = List('a','b','c','d')
val s2 = List('1','2','3','4')
val s3 = List("aa","ab","ac","ad")
val s4 = List('e','f','g','h')
val s5 = List('5','6','7','8')
val s6 = List("ba","bb","bc","bd")
val s7 = List("ca","cb","cc","cd")   


val preS3  = s1 zip s2 map{ case (x1,x2) => (x1,x2)}
val preS4  = preS3  zip s3  map{ case (x1,x2) => (x1._1,x1._2,x2)}
val preS5  = preS4  zip s4  map{ case (x1,x2) => (x1._1,x1._2,x1._3,x2)}
val preS6  = preS5  zip s5  map{ case (x1,x2) => (x1._1,x1._2,x1._3,x1._4,x2)}
val preS7  = preS6  zip s6  map{ case (x1,x2) => (x1._1,x1._2,x1._3,x1._4,x1._5,x2)}
val preS8  = preS7  zip s7  map{ case (x1,x2) => (x1._1,x1._2,x1._3,x1._4,x1._5,x1._6,x2)}

Thanks in advance.

Jeffrey Chung
  • 18,571
  • 7
  • 29
  • 49
Ahmad
  • 269
  • 1
  • 4
  • 13
  • Possible duplicate of [Can I zip more than two lists together in Scala?](https://stackoverflow.com/questions/1664439/can-i-zip-more-than-two-lists-together-in-scala) – Jeffrey Chung Oct 25 '19 at 21:39

3 Answers3

3

Here is a way based on this answer

scala> :paste
// Entering paste mode (ctrl-D to finish)

val s1 = List('a','b','c','d')
val s2 = List('1','2','3','4')
val s3 = List("aa","ab","ac","ad")
val s4 = List('e','f','g','h')
val s5 = List('5','6','7','8')
val s6 = List("ba","bb","bc","bd")
val s7 = List("ca","cb","cc","cd")   

// Exiting paste mode, now interpreting.

s1: List[Char] = List(a, b, c, d)
s2: List[Char] = List(1, 2, 3, 4)
s3: List[String] = List(aa, ab, ac, ad)
s4: List[Char] = List(e, f, g, h)
s5: List[Char] = List(5, 6, 7, 8)
s6: List[String] = List(ba, bb, bc, bd)
s7: List[String] = List(ca, cb, cc, cd)

scala> for (e1 Tuple2 e2 Tuple2 e3 Tuple2 e4 Tuple2 e5 Tuple2 e6 Tuple2 e7 <- s1 zip s2 zip s3 zip s4 zip s5 zip s6 zip s7) yield (e1, e2, e3, e4, e5, e6, e7)
res0: List[(Char, Char, String, Char, Char, String, String)] = List((a,1,aa,e,5,ba,ca), (b,2,ab,f,6,bb,cb), (c,3,ac,g,7,bc,cc), (d,4,ad,h,8,bd,cd))
jq170727
  • 9,278
  • 2
  • 32
  • 50
2

This is the basic algorithm for three lists:
(As you can see it finish as soon as any of the lists runs out of elements)

def zipThree[A, B, C](as: List[A], bs: List[B], cs: List[C]): List[(A, B, C)] = {
  @annotation.tailrec
  def loop(as: List[A], bs: List[B], cs: List[C], acc: List[(A, B, C)]): List[(A, B, C)] =
    (as, bs, cs) match {
      case (a :: as, b :: bs, c :: cs) =>
        loop(as, bs, cs, (a, b, c) :: acc)

      case _ =>
        // Return as soon as one list ends.
        acc.reverse
    }

  loop(as, bs, cs, acc = List.empty)
}

You can use it like this:

zipThree(List(1, 2), List('a', 'b'), List(true, false))
// res: List[(Int, Char, Boolean)] = List((1, 'a', true), (2, 'b', false))

Now, what to do for four, five, six, or more elements (up to 22)?
Well, basically the same but with one extra parameter everywhere.

This task is very repetitive an easy to get wrong with many lists, I would recommend you to write a source generator to create a file with all the cases from three up to twenty two.

0

Using Typelevel Cats:

import cats.implicits._
(s1, s2, s3, s4, s5, s6, s7).parTupled
Oleg Pyzhcov
  • 6,968
  • 1
  • 15
  • 30