In Scala, is it possible to zip two lists of differing sizes?

You could do a simple one liner, using the map method

val letters = List('a', 'b', 'c', 'd', 'e')
val numbers = List(1, 2)

val longZip1 = letters.zipWithIndex.map( x => (x._1, numbers(x._2 % numbers.length)) )

//or, using a for loop
//for (x <- letters.zipWithIndex) yield (x._1, numbers(x._2 % numbers.size))

And let's consider your lists are way longer:

val letters = List('a', 'b', 'c', 'd', 'e' /* 'f', ...*/)
val numbers = List(1, 2 /* 3, ... */)
val (longest, shortest) = (letters.toArray, numbers.toArray)

val longZip1 = longest
                 .zipWithIndex
                 .map(x => (x._1, shortest(x._2 % shortest.length)))

The shorter of the lists needs to be repeated indefinitely. In this case it's obvious that numbers is shorter, but in case you need it to work in general, here is how you can do it:

def zipLongest[T](list1 : List[T], list2 : List[T]) : Seq[(T, T)] =
  if (list1.size < list2.size)
    Stream.continually(list1).flatten zip list2
  else
    list1 zip Stream.continually(list2).flatten

val letters = List('a', 'b', 'c', 'd', 'e')
val numbers = List(1, 2)

println(zipLongest(letters, numbers))

Your letters and numbers are tuples, not lists. So let's fix that

scala> val letters = List('a', 'b', 'c', 'd', 'e')
letters: List[Char] = List(a, b, c, d, e)

scala> val numbers = List(1,2)                    
numbers: List[Int] = List(1, 2)

Now, if we zip them we don't get the desired result

scala> letters zip numbers
res11: List[(Char, Int)] = List((a,1), (b,2))

But that suggests that if numbers were repeated infinitely then the problem would be solved

scala> letters zip (Stream continually numbers).flatten
res12: List[(Char, Int)] = List((a,1), (b,2), (c,1), (d,2), (e,1))

Unfortunately, that's based on knowledge that numbers is shorter than letters. So to fix it all up

scala> ((Stream continually letters).flatten zip (Stream continually numbers).flatten take (letters.size max numbers.size)).toList
res13: List[(Char, Int)] = List((a,1), (b,2), (c,1), (d,2), (e,1))

Tags:

Scala