hi there, small question: having 2 lists such as `...
# announcements
a
hi there, small question: having 2 lists such as
[1, 2, 3]
and
[4, 5, 6, 7]
is there an existing function that intercalates both so the result is
[1, 4, 2, 5, 3, 6, 7]
?
I just came up with this, but wondering if there's something already built-in
Copy code
fun <E> List<E>.merge(other: List<E>): List<E> {
    val out = ArrayList<E>(size + other.size)
    forEachIndexed { index, e ->
        out.add(e)
        if (index < other.size) out.add(other[index])
    }
    return out
}
d
la.zip(lb) { a, b -> listOf(a, b) }.flatten()
almost works, in that it only keeps the length of the shortest list
w
Check if this suits you:
Copy code
@Test
    fun asas1() {
        val l1 = listOf(1, 2, 3)
        val l2 = listOf(4, 5, 6, 7)
        val expected = listOf(1, 4, 2, 5, 3, 6, 7)

        val result =
                l1.zip(l2).flatMap { listOf(it.first, it.second) } +
                        l1.drop(l2.size) + l2.drop(l1.size)

        assertEquals(expected, result)
    }

    @Test
    fun asas2() {
        val l1 = listOf(4, 5, 6, 7)
        val l2 = listOf(1, 2, 3)
        val expected = listOf(4, 1, 5, 2, 6, 3, 7)

        val result =
                l1.zip(l2).flatMap { listOf(it.first, it.second) } +
                        l1.drop(l2.size) + l2.drop(l1.size)

        assertEquals(expected, result)
    }
Can have this extension:
Copy code
fun <T> List<T>.mix(other: List<T>) =
            this.zip(other).flatMap { listOf(it.first, it.second) } +
                    this.drop(other.size) + other.drop(this.size)
r
Most of those solutions are very inefficient, hopefully we’re not talking about huge lists here
a
Ok, I see, thanks @wbertan! I think I'll keep with my function for now
👍 1
p
@aballano Note, that your function returns
[1, 4, 2, 5, 3, 6]
instead of
[1, 4, 2, 5, 3, 6, 7]
for your example.
👍 1
r
I would use something more like this (untested)
Copy code
fun <T> Iterable<T>.alternateWith(other: Iterable<T>): Iterable<T> =
    Iterable {
        object : Iterator<T> {

            private val a = this@alternateWith.iterator()
            private val b = other.iterator()
            private var switch = false

            override fun hasNext(): Boolean =
                a.hasNext() || b.hasNext()

            override fun next(): T {
                switch = !switch
                return if (switch) next(b, a) else next(a, b)
            }

            private fun next(first: Iterator<T>, second: Iterator<T>): T =
                if (first.hasNext()) first.next() else second.next()

        }
    }