7

How can I merge two lists / Seqs so it takes 1 element from list 1, then 1 element from list 2, and so on, instead of just appending list 2 at the end of list 1?

E.g [1,2] + [3,4] = [1,3,2,4]

and not [1,2,3,4]

Any ideas? Most concat methods I've looked at seem to do to the latter and not the former.

Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
Ali
  • 261,656
  • 265
  • 575
  • 769

4 Answers4

7

Another way:

List(List(1,2), List(3,4)).transpose.flatten
Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
6

So maybe your collections aren't always the same size. Using zip in that situation would create data loss.

def interleave[A](a :Seq[A], b :Seq[A]) :Seq[A] =
  if (a.isEmpty) b else if (b.isEmpty) a
  else a.head +: b.head +: interleave(a.tail, b.tail)

interleave(List(1, 2, 17, 27)
          ,Vector(3, 4))  //res0: Seq[Int] = List(1, 3, 2, 4, 17, 27)
jwvh
  • 50,871
  • 7
  • 38
  • 64
5

Try

List(1,2)
  .zip(List(3,4))
  .flatMap(v => List(v._1, v._2))

which outputs

res0: List[Int] = List(1, 3, 2, 4)

Also consider the following implicit class

implicit class ListIntercalate[T](lhs: List[T]) {
  def intercalate(rhs: List[T]): List[T] = lhs match {
    case head :: tail => head :: (rhs.intercalate(tail))
    case _ => rhs
  }
}

List(1,2) intercalate List(3,4)
List(1,2,5,6,6,7,8,0) intercalate List(3,4)

which outputs

res2: List[Int] = List(1, 3, 2, 4)
res3: List[Int] = List(1, 3, 2, 4, 5, 6, 6, 7, 8, 0)
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
5

You can do:

val l1 = List(1, 2)
val l2 = List(3, 4)
l1.zip(l2).flatMap { case (a, b) => List(a, b) }
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118