Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Kotlin辞典

  1. トップページ
  2. Kotlin辞典
  3. リスト — zip() / unzip()

リスト — zip() / unzip()

Kotlinの『zip()』は2つのリストを要素ごとにペアにしたリストを返します。『unzip()』はペアのリストを2つのリストに分解します。リストの並列処理や、複数のデータ列を結合する場合に使います。

構文
val names = listOf("Alice", "Bob", "Carol")
val scores = listOf(85, 72, 91)

// zip — 対応する要素を Pair にします。
val zipped = names.zip(scores)
// [Pair("Alice", 85), Pair("Bob", 72), Pair("Carol", 91)]

// zip with transform — カスタム変換します。
val results = names.zip(scores) { name, score -> "$name: $score点" }

// unzip — Pair のリストを2つのリストに分解します。
val (n, s) = zipped.unzip()  // names, scores に戻ります。
メソッド一覧
メソッド概要
リストA.zip(リストB)2つのリストを Pair のリストに結合します。短い方の長さに合わせます。
リストA.zip(リストB) { a, b -> 変換 }変換ラムダを指定して zip します。
ペアリスト.unzip()Pair<A, B> のリストを Pair<List<A>, List<B>> に分解します。
リスト.zipWithNext()隣り合う要素のペアのリストを返します(差分計算などに使います)。
リスト.zipWithNext { a, b -> }隣り合う要素を変換してリストを返します。
サンプルコード
fun main() {
    // 基本の zip
    val names = listOf("Alice", "Bob", "Carol", "Dave")
    val scores = listOf(85, 72, 91, 68)
    val ages = listOf(25, 30, 28)  // 短い方に合わせます(3件)

    val zipped = names.zip(scores)
    println("zip: $zipped")

    // zip with transform(変換付き)
    val results = names.zip(scores) { name, score ->
        "$name: ${score}点 (${if (score >= 80) "合格" else "不合格"})"
    }
    results.forEach { println(it) }

    println()

    // 長さが異なる場合(短い方に合わせます)
    val nameAge = names.zip(ages)
    println("長さ違い zip: $nameAge")  // 3件

    println()

    // unzip — Pair を2つのリストに分解します。
    val (nameList, scoreList) = zipped.unzip()
    println("名前: $nameList")
    println("点数: $scoreList")

    println()

    // zipWithNext — 隣接要素のペアを作ります(差分計算)
    val temps = listOf(20.0, 22.5, 19.0, 25.0, 23.0)
    println("気温変化:")
    temps.zipWithNext { today, tomorrow ->
        val diff = tomorrow - today
        val dir = if (diff > 0) "↑" else if (diff < 0) "↓" else "→"
        println("  ${today}℃ $dir ${tomorrow}℃ (${"%.1f".format(diff)})")
    }

    println()

    // 3つのリストを zip(2回のzipで対応)
    val first = listOf(1, 2, 3)
    val second = listOf("a", "b", "c")
    val third = listOf(true, false, true)
    val triple = first.zip(second).zip(third) { (a, b), c -> Triple(a, b, c) }
    triple.forEach { println(it) }
}
概要

『zip()』は2つのリストを対応させて処理するときに便利です。長さが異なる場合は短い方に合わせて切り捨てられます(例外は発生しません)。

『zipWithNext()』は連続する2要素の差分や変化率を計算するときに使います。for ループで添字を使う処理の代わりになります。

リストの平坦化はリスト — flatMap() / flatten()を、畳み込みはリスト — reduce() / fold()を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。