Kotlin zipAll alternative

Does Kotlin have a zipAll function in Scala?

In scala, I can make a sum of two arrays with different lengths using the zipAll function.

Scala:

val arrA = Array(1,2,3)
val arrB = Array(4, 5)
arrA.zipAll(arrB, 0, 0).map(x => x._1 + x._2)

Or what is the right way to do this in Kotlin?

+4
source share
3 answers

Kotlin 1.0 has no built-in counterpart. It would be nice to add it to stdlib. Feel free to post a problem on the YouTrack page

+7
source

I made a quick recursive version for fun. Not very effective, though due to adding a list.

fun <T, U> List<T>.zipAll(that: List<U>, elem1: T, elem2: U): List<Pair<T, U>> {
    tailrec fun helper(first: List<T>, second: List<U>, acc: List<Pair<T, U>>): List<Pair<T, U>> {
        return when {
            first.isEmpty() && second.isEmpty() -> acc
            first.isEmpty() -> helper(first, second.drop(1), acc + listOf(elem1 to second.first()))
            second.isEmpty() -> helper(first.drop(1), second, acc + listOf(first.first() to elem2))
            else -> helper(first.drop(1), second.drop(1), acc + listOf(first.first() to second.first()))
        }
    }

    return helper(this, that, emptyList())
}
0
source

zipAll Kotlin:

fun <T1: Any, T2: Any> List<T1>.zipAll(other: List<T2>, emptyValue: T1, otherEmptyValue: T2): List<Pair<T1, T2>> {
    val i1 = this.iterator()
    val i2 = other.iterator()
    return generateSequence {
        if (i1.hasNext() || i2.hasNext()) {
            Pair(if (i1.hasNext()) i1.next() else emptyValue,
                    if (i2.hasNext()) i2.next() else otherEmptyValue)
        } else {
            null
        }
    }.toList()
}

unit test:

@Test fun sumTwoUnevenLists() {
    val x = listOf(1,2,3,4,5)
    val y = listOf(10,20,30)

    assertEquals(listOf(11,22,33,4,5), x.zipAll(y, 0, 0).map { it.first + it.second })
}

, , .. , . :

fun <T1: Any, T2: Any> Array<T1>.zipAll(other: Array<T2>, emptyValue: T1, otherEmptyValue: T2): List<Pair<T1, T2>> {
    val largest = this.size.coerceAtLeast(other.size)
    val result = arrayListOf<Pair<T1, T2>>()
    (0..this.size.coerceAtLeast(other.size)-1).forEach { i ->
        result.add(Pair(if (i < this.size) this[i] else emptyValue, if (i < other.size) other[i] else otherEmptyValue))
    }
    return result.filterNotNull()
}

List, map .

0
source

All Articles