KotlinにはScalaのzipAllのような機能がありますか?Kotlin zipすべての代替
スカラーでは、長さの異なる2つの配列の和をzipAll関数で使用できます。
スカラ:
val arrA = Array(1,2,3)
val arrB = Array(4, 5)
arrA.zipAll(arrB, 0, 0).map(x => x._1 + x._2)
それともKotlinでこれを行うための正しい方法は何ですか?
KotlinにはScalaのzipAllのような機能がありますか?Kotlin zipすべての代替
スカラーでは、長さの異なる2つの配列の和をzipAll関数で使用できます。
スカラ:
val arrA = Array(1,2,3)
val arrB = Array(4, 5)
arrA.zipAll(arrB, 0, 0).map(x => x._1 + x._2)
それともKotlinでこれを行うための正しい方法は何ですか?
Kotlin 1.0にはビルド中のアナログはありません。それをstdlibに追加することをお勧めします。お気軽にYouTrackで問題を提出してください
私は楽しいために素早くテール再帰的なバージョンを作った。しかし、非常に効率的ではない、リストのために追加します。ここ
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())
}
はKotlinため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 })
}
同じ等アレイ、他のコレクション型、配列、ANに適用することができます配列にインデックスを付けることができるので、配列のみのバージョンは簡単になります。配列バージョンは次のようになります。
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()
}
map
機能はとにかくリストにあなたを回すために起こっているので、それはList
を返します。
お返事ありがとうございます。私は問題https://youtrack.jetbrains.com/issue/KT-13017を提出しました。 – Oleg
投票ありがとうございました! – voddan