Kotlin zipAll替代品

时间:2016-07-06 20:01:41

标签: scala kotlin

Kotlin在Scala中的功能是否像zipAll一样?

在scala中,我可以使用不同长度的两个数组的总和使用zipAll函数。

Scala的:

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

或者在Kotlin中这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:7)

Kotlin 1.0中没有内置模拟。将它添加到stdlib中可能是个好主意。随意在YouTrack上提出问题

答案 1 :(得分:2)

以下是Kotlin的$(document).ready(function(){ $("#Diagnosing").click(function(){ $('#message').html('Hi, Thanks for coming in! We are currently diagnosing your machine. We\'ll let you know what the issue is as soon as we finish.'); }); $("#Diagnosis").click(function(){ $('#message').html('Hi, We took a look at your device, and the issue is *. It will be $ +tax to repair. Shall we proceed with the fix?'); }); $("#Approved").click(function(){ $('#message').html('Your device has been marked as approved! We will proceed with the fix and let you know when it\'s ready to be picked up!'); }); $("#Declined").click(function(){ $('#message').html('Your repair has been marked as declined. Please let us know if there is anything we can do to change your mind!'); }); $("#Parts").click(function(){ $('#message').html('Your parts have been ordered. We will let you know when we receive the parts and begin installing them.'); }); $("#Progress").click(function(){ $('#message').html('We are currently working on your repair. We will notify you when it is done!'); }); $("#Completed").click(function(){ $('#message').html('Hey there - your repair is all set! We just finished cleaning it up so you can come pick it up and pay at your earliest convenience. We *** and tested ***.'); }); $("#Closed").click(function(){ $('#message').html('The ticket has been closed. Thank you.'); }); });

zipAll

单元测试:

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()
}

同样可以应用于数组,其他集合类型,序列等。由于您可以索引到数组,因此只有数组的版本会更容易。阵列版本可以是:

@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函数无论如何都会把你变成一个列表。

答案 2 :(得分:1)

我制作了一个快速的尾递归版本以获得乐趣。但是,由于列表附加,效率不高。

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())
}