 marcin -4 years ago 140
Scala Question

# How can i interleave elements of 2 lists in scala

I'd like to combine two Lists of arbitrary length in such a way that elements from the 2nd List are inserted after every n-th element into the 1st List. If the 1st List length is less than n, no insertion results.

So having

``````val a = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
val b = List(101,102,103)
val n = 3
``````

I want the resulting List to look like this:

``````List(1,2,3,101,4,5,6,102,7,8,9,103,10,11,12,13,14,15)
``````

I have this working using a
`foldLeft`
on
`a`
, but I'm wondering how the same logic could be accomplished using Scalaz? Yo Eight

Meet my apomorphism friend

``````def apo[A, B](v: B)(f: B => Option[(A, Either[B, List[A]])]): List[A] = f(v) match {
case None => Nil
case Some((a, Left(b)))   => a :: apo(b)(f)
case Some((a, Right(as))) => a :: as
}
``````

Your interleave method can be implemented like this

``````def interleave[A](period: Int, substitutes: List[A], elems: List[A]): List[A] =
apo((period, substitutes, elems)){
case (_, _, Nil)       => None
case (_, Nil, v :: vs) => Some((v, Right(vs)))
case (0, x :: xs, vs)  => Some((x, Left((period, xs, vs))))
case (n, xs, v :: vs)  => Some((v, Left((n - 1, xs, vs))))
}
``````

This gives:

``````scala> interleave(3, b, a)
res1: List[Int] = List(1, 2, 3, 101, 4, 5, 6, 102, 7, 8, 9, 103 , 10, 11 , 12, 13, 14, 15)
``````

The good point is the computation ends when a or b are Nil unlike foldLeft. The bad news is interleave is no more tail recursive

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download