範囲・for ループ
| 対応: | Kotlin 1.0(2016) |
|---|
Kotlin の範囲(Range)は『..』や『until』などで数値の区間を表すオブジェクトです。『for』ループと組み合わせることで、簡潔な繰り返し処理が書けます。
構文
// 範囲の生成
1..10 // 1 以上 10 以下(終端を含む)
1 until 10 // 1 以上 10 未満(終端を含まない)
10 downTo 1 // 10 から 1 へ降順
1..10 step 2 // 1, 3, 5, 7, 9(ステップ指定)
// for ループの基本形
for (変数 in 範囲またはコレクション) {
// 処理
}
構文一覧
| 構文 | 概要 |
|---|---|
| a..b | a 以上 b 以下の閉区間を表します。文字の範囲にも使えます。 |
| a until b | a 以上 b 未満の半開区間を表します。インデックスの最大値に合わせやすいため配列走査でよく使います。 |
| a downTo b | a から b へ降順の範囲を表します。 |
| 範囲 step n | ステップ幅を n に指定します。 |
| in 範囲 | 値が範囲に含まれるか判定します。 |
| !in 範囲 | 値が範囲に含まれないか判定します。 |
| withIndex() | コレクションをインデックス付きで反復します。 |
サンプルコード
sample_range_for.kt
fun main() {
// 基本的な範囲ループ
for (i in 1..5) {
print("$i ") // 1 2 3 4 5
}
println()
// until で終端を含まないループ
val list = listOf("A", "B", "C")
for (i in 0 until list.size) {
print("${list[i]} ") // A B C
}
println()
// downTo で逆順ループ
for (i in 5 downTo 1) {
print("$i ") // 5 4 3 2 1
}
println()
// step でステップ幅を指定
for (i in 0..10 step 3) {
print("$i ") // 0 3 6 9
}
println()
// コレクションを直接 for で反復できる
val pilots = listOf("綾波レイ", "碇シンジ", "惣流アスカ")
for (pilot in pilots) {
println(pilot)
}
// インデックスも取得したい場合は withIndex() を使う
for ((index, value) in pilots.withIndex()) {
println("$index: $value")
}
// 範囲の in 演算子で包含判定もできる
val score = 85
if (score in 70..89) {
println("B ランクです")
}
// 文字の範囲も使える
for (ch in 'A'..'E') {
print("$ch ") // A B C D E
}
}
コンパイルして実行すると次のようになります。
kotlinc sample_range_for.kt -include-runtime -d sample_range_for.jar java -jar sample_range_for.jar 1 2 3 4 5 A B C 5 4 3 2 1 0 3 6 9 綾波レイ 碇シンジ 惣流アスカ 0: 綾波レイ 1: 碇シンジ 2: 惣流アスカ B ランクです。 A B C D E
よくあるミス
fun main() {
val pilots = listOf("綾波レイ", "碇シンジ", "惣流アスカ")
// .. で終端を含む範囲を使うとインデックスが範囲外になる
// for (i in 0..pilots.size) { // 0..3 になり pilots[3] で IndexOutOfBoundsException
// println(pilots[i])
// }
// downTo の代わりに負のステップを使おうとする
// for (i in 5..-1) // これは空の範囲になる(降順にはならない)
// step に負の値を渡す(実行時エラー)
// for (i in 0..10 step -2) // IllegalArgumentException: Step must be positive
}
正しい書き方は『until』か『indices』を使い、降順は『downTo』、降順ステップは『downTo step』を組み合わせる。
sample_range_for_ok.kt
fun main() {
val pilots = listOf("綾波レイ", "碇シンジ", "惣流アスカ")
// until でインデックス範囲外を防ぐ
for (i in 0 until pilots.size) {
println(pilots[i])
}
// downTo で降順ループ
for (i in 3 downTo 1) {
println("カウントダウン: $i")
}
// 降順ステップは downTo と step を組み合わせる
for (i in 10 downTo 0 step 3) {
print("$i ")
}
println()
}
コンパイルして実行すると次のようになります。
kotlinc sample_range_for_ok.kt -include-runtime -d sample_range_for_ok.jar java -jar sample_range_for_ok.jar 綾波レイ 碇シンジ 惣流アスカ カウントダウン: 3 カウントダウン: 2 カウントダウン: 1 10 7 4 1
概要
Kotlin の範囲はコレクションのインデックス操作でよく活用されます。配列やリストのインデックス走査には『0 until list.size』よりも『list.indices』を使うとより簡潔です。また、ラベル付き break・continue(例: 『break@outer』)で多重ループの制御も可能です。
範囲は『when』の中でも使えます(詳細は『when 式』を参照)。高階関数を使った反復には『高階関数』も参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。