言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Kotlin辞典

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

リスト — forEach() / forEachIndexed()

対応: Kotlin 1.0(2016)

Kotlinの『forEach()』はリストの各要素に対してラムダを実行します。『forEachIndexed()』はインデックスと要素を同時に受け取れます。繰り返し処理の基本メソッドです。

構文

val fruits = listOf("りんご", "バナナ", "オレンジ")

// forEach — 各要素で処理を実行します
fruits.forEach { println(it) }

// forEachIndexed — インデックスも使います
fruits.forEachIndexed { index, fruit ->
    println("$index: $fruit")
}

// for ループと同等です
for ((index, fruit) in fruits.withIndex()) {
    println("$index: $fruit")
}

メソッド一覧

メソッド概要
リスト.forEach { it }各要素に対してラムダを実行します。戻り値はありません(Unit)。
リスト.forEachIndexed { i, v -> }インデックスと要素を引数にラムダを実行します。
リスト.withIndex()インデックスと要素のペア(IndexedValue)のリストを返します。
リスト.onEach { it }forEach と同じですが、元のコレクション自身を返します(チェーン可能)。
マップ.forEach { (k, v) -> }マップのキーと値を分割して受け取ります。

サンプルコード

sample_list_foreach.kt
data class Student(val name: String, val score: Int)

fun main() {
    val students = listOf(
        Student("member_a", 85),
        Student("member_b", 72),
        Student("member_c", 91),
        Student("member_d", 68)
    )

    // 基本の forEach
    println("=== 成績一覧 ===")
    students.forEach { student ->
        println("${student.name}: ${student.score}点")
    }

    println()

    // forEachIndexed で番号付き出力
    println("=== 番号付き ===")
    students.forEachIndexed { index, student ->
        val rank = index + 1
        println("$rank 位 ${student.name}: ${student.score}点")
    }

    println()

    // マップでの forEach(キーと値を分割)
    val capitals = mapOf("日本" to "東京", "フランス" to "パリ", "アメリカ" to "ワシントンD.C.")
    println("=== 首都一覧 ===")
    capitals.forEach { (country, capital) ->
        println("$country の首都: $capital")
    }

    println()

    // onEach — forEach と同じですがチェーンできます
    val names = students
        .onEach { println("処理中: ${it.name}") }
        .map { it.name }
    println("名前リスト: $names")

    println()

    // withIndex で for ループ
    println("=== withIndex ===")
    for ((i, s) in students.withIndex()) {
        println("[$i] ${s.name}")
    }
}
list_foreach.kt
kotlinc list_foreach.kt -include-runtime -d list_foreach.jar
java -jar list_foreach.jar
=== 成績一覧 ===
member_a: 85点
member_b: 72点
member_c: 91点
member_d: 68点

=== 番号付き ===
1 位 member_a: 85点
2 位 member_b: 72点
3 位 member_c: 91点
4 位 member_d: 68点

=== 首都一覧 ===
日本 の首都: 東京
フランス の首都: パリ
アメリカ の首都: ワシントンD.C.

処理中: member_a
処理中: member_b
処理中: member_c
処理中: member_d
名前リスト: [member_a, member_b, member_c, member_d]

=== withIndex ===
[0] member_a
[1] member_b
[2] member_c
[3] member_d

よくあるミス

『forEach』の戻り値を使おうとするミスがあります。『forEach』は『Unit』を返すため、変換結果をリストとして得ることはできません。変換結果を集めたい場合は『map』が使えます。

『forEach』の中で『break』しようとするミスもあります。『forEach』はラムダなので『break』・『continue』は使えません。途中で抜けたい場合は通常の『for』ループが使えます。

下記のサンプルコードで、正しい使い方を確認できます。

sample_list_foreach_mistakes.kt
data class Student(val name: String, val score: Int)

fun main() {
    val students = listOf(
        Student("member_a", 85),
        Student("member_b", 72),
        Student("member_c", 91),
        Student("member_d", 68)
    )

    // 変換結果が必要なときは map を使う
    val names = students.map { it.name }
    println("名前: $names")

    // ループを抜けたいときは for ループを使う
    for (s in students) {
        if (s.score >= 90) break
        println("90点未満: ${s.name}")
    }

    // ラムダだけを抜けたいときは return@forEach を使う
    students.forEach { s ->
        if (s.score < 70) return@forEach // このラムダだけスキップ
        println("合格: ${s.name}")
    }

    // forEachIndexed は index が第1引数
    students.forEachIndexed { index, student ->
        println("$index: ${student.name}")
    }
}

コンパイルして実行すると次のようになります。

kotlinc sample_list_foreach_mistakes.kt -include-runtime -d sample_list_foreach_mistakes.jar
java -jar sample_list_foreach_mistakes.jar
名前: [member_a, member_b, member_c, member_d]
90点未満: member_a
90点未満: member_b
合格: member_a
合格: member_b
合格: member_c
0: member_a
1: member_b
2: member_c
3: member_d

概要

『forEach()』は副作用(ログ出力・DBへの書き込みなど)を伴う処理に使います。変換結果が必要な場合は『map()』、条件に合う要素を絞り込む場合は『filter()』を使うと、意図がより明確になります。

『forEach』の中でループを抜け出したい場合は『return@forEach』でラムダからリターンできます(通常の『return』は外側の関数を返します)。ループを完全に中断するには『for』ループと『break』を使います。

リストの基本操作はリスト — 生成 / listOf() / mutableListOf()を、フィルタリングと変換はリスト — filter() / map()を参照してください。

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