2016-07-06 5 views
4

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でこれを行うための正しい方法は何ですか?

答えて

7

Kotlin 1.0にはビルド中のアナログはありません。それをstdlibに追加することをお勧めします。お気軽にYouTrackで問題を提出してください

+0

お返事ありがとうございます。私は問題https://youtrack.jetbrains.com/issue/KT-13017を提出しました。 – Oleg

+0

投票ありがとうございました! – voddan

0

私は楽しいために素早くテール再帰的なバージョンを作った。しかし、非常に効率的ではない、リストのために追加します。ここ

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

は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を返します。