1. 序章

ループは、あらゆるプログラミング言語の基本的な構成要素の1つです。 これらは、条件が満たされるまで1つ以上のステートメントを繰り返し実行できるようにします。

このチュートリアルでは、Kotlinでサポートされているさまざまなタイプのループを見ていきます。

  • 繰り返す
  • forループ
  • whileループ
  • do..whileループ

repeatステートメントを見てみましょう。

2. 繰り返し

repeat ステートメントは、すべてのKotlinループの中で最も基本的なものです。 操作をn回繰り返すだけの場合は、repeat。を使用できます。

たとえば、 HelloWorldを2回印刷してみましょう。

repeat(2) {
    println("Hello World")
}

さらに、現在の反復のゼロベースのインデックスにアクセスすることもできます。

repeat(2) { index ->
    println("Iteration ${index + 1}: Hello World")
}

3. Forループ

for ループは、値のシーケンスを反復処理するために使用されます。 シーケンス内の値ごとにステートメントのブロックを実行します。

forループの構文を見てみましょう。

for (variableDeclaration 'in' expression) {
    // block of statements
}

Kotlinのforループを使用して、範囲、配列、コレクションなどの任意のIterableを反復処理できます

3.1. 値の範囲で反復する

範囲は、開始、終了、およびステップで構成される一連の値です。 Kotlinでは、forループと範囲式の組み合わせを使用して範囲を反復処理できます。

3.2. 配列の反復

まず、母音の配列を宣言しましょう。

val vowels = arrayOf('a', 'e', 'i', 'o', 'u')

これで、 for ループを使用して、この配列の要素を反復処理できます。

for (vowel in vowels) {
    println(vowel)
}

次に、配列のインデックスを繰り返し処理してみましょう。 これを行うには、インデックスプロパティをループします。

for (index in vowels.indices) {
    println(vowels[index])
}

indexs プロパティは、反復可能なIntRangeとして配列インデックスのみを返します。 返されたインデックスを使用して、配列要素を個別にフェッチする必要があります。

インデックスと要素の両方を同時に提供する別の方法を見てみましょう。

for ((index, vowel) in vowels.withIndex()) {
    println("The vowel at index $index is: $vowel")
}

このforループの興味深い構文をもう少し理解しましょう。

for ((index, vowel) in vowels.withIndex()) { ... }

withIndex()メソッドは、IndexedValueインスタンスを返します。 destructuring 宣言を使用し、 component1()によって返される( index、 value)プロパティをキャプチャします。 IndexedValuecomponent2()メソッドをそれぞれインデックスおよび母音変数に追加します。

3.3. リストの反復

リストは、重複する値を含む可能性のある要素の一般的な順序付きコレクションです。 for ループを使用して、リストの要素を反復することができます。 また、要素のインデックスによってリストを反復することもできます。

3.4. マップ上での反復

国名でキー設定された首都名のマップを宣言することから始めましょう。

val capitalCityByCountry = mapOf("Netherlands" to "Amsterdam",
  "Germany" to "Berlin", "USA" to "Washington, D.C.")

これで、マップエントリを反復処理して、各エントリのキーの両方にアクセスできます。

for (entry in capitalCityByCountry) {
    println("The capital city of ${entry.key} is ${entry.value}")
}

keys プロパティを使用して、マップのキーを反復処理できます。

for (country in capitalCityByCountry.keys) {
    println(country)
}

ここでは、マップのキーの読み取り専用Setを返すkeysプロパティを繰り返し処理します。

同様に、 values プロパティを使用して、マップの値を反復処理できます。

for (capitalCity in capitalCityByCountry.values) {
    println(capitalCity)
}

最後に、配列やリストの場合と同様に、マップを反復処理するときにも破壊宣言を使用できます。

for ((country, capitalCity) in capitalCityByCountry) {
    println("The capital city of $country is $capitalCity")
}

破壊宣言により、マップを反復処理するときに、各エントリのキーおよびにアクセスできます。

3.5. forEachを使用した機能スタイルの反復

これまで、 for ループを使用して、配列、コレクション、および範囲を反復処理する従来のスタイルについて説明してきました。

機能スタイルでコーディングするには、代わりにforEachを使用できます。

4. Whileループ

whileループはステートメントのブロックを繰り返しますwhileその制御ブール式はtrueです。

最初に構文を見てみましょう。

while (boolean-expression) {
    // statements here
}

次に、例を見てみましょう。

var counter = 0
while (counter < 5) {
    println("while loop counter: " + counter++)
}

これにより、0から4までのカウンター値が出力されます。

while ループでは、boolean-expressionが最初に評価されます。 これは、最初の反復でboolean-expressionfalseと評価された場合、ステートメントのブロックが実行されないことを意味します。

これがwhileループであり、そのステートメントのブロックは決して実行されません。

while (false) {
    println("This will never be printed")
}

これが無限のwhileループです。

while (true) {
    println("I am in an infinite loop")
}

5. Do..Whileループ

do..while ループは、 boolean-expression が各反復後に評価されるという点で、whileループの変形です。

do {
    // statements here
} while (boolean-expression)

簡単な例を見てみましょう。

var counter = 0
do {
    println("do..while counter: " + counter++)
} while (counter < 5)

これにより、0から4までのカウンター値が出力されます。

boolean-expression は各ループの最後で評価されるため、do..whileループは少なくとも1回実行されます。

これがdo..whileループであり、そのステートメントのブロックは1回だけ実行されます。

do {
    println("This will be printed exactly once")
} while (false)

6. 戻り、中断、続行キーワード

ループを終了したり、ループの次の反復をスキップしたりしたい場合があります。 このような場合、構造ジャンプ式を使用できます。

Kotlinには3つの構造的なジャンプ式があります。 戻り、中断し、続行します。 

ただし、ループに複数のbreakまたはcontinueステートメントが含まれている場合、それはコードの臭いと見なされるため、回避する必要があります。

7. 複数の変数でループする

これまで、単一の変数でループするさまざまな方法を学びました。 このセクションでは、ループに関する知識を複数の変数に拡張します。

7.1. zip演算子

2つのチーム間で複数の2人ゲームを編成する必要があると想像してみましょう。

val teamA = listOf("A1", "A2", "A3")
val teamB = listOf("B1", "B2")

2つのチームのプレーヤーの数が異なるため、すべてのプレーヤーが同時にプレイできるわけではありません。 ただし、zip演算子を使用して、リストに表示される順序でそれらをペアリングし、teamAの3番目のプレーヤーA3を無視することができます。

teamA zip teamB

showMatches()関数を作成して、任意の2つのチーム間の一致を生成して表示してみましょう。

fun showMatches(team1: List<String>, team2: List<String>) {
    for ((player1, player2) in team1 zip team2)
        println("$player1 vs $player2")
}

次に、 showMatches(teamA、teamB)を呼び出したときに生成される一致を確認しましょう。

A1 vs B1
A2 vs B2

あるいは、複数の変数、つまりplayer1player2をループするこの問題を、単一の変数matchをループするように変換することもできます。

fun showMatchLabels(team1: List<String>, team2: List<String>) {
    matches = team1.zip(team2) { player1, player2 -> "$player1 vs $player2" }
    for (match in matches)
        println(match)
}

基本的に、2つのリストを1つのリストに結合し、一致するラベルが含まれるようにしました。

7.2. 九九

範囲の概念とzip演算子を適用して、各行が次の形式で表示される掛け算の九九を生成することにより、複数の変数を使用したループの理解を深めましょう。

factor x multiplier = result

係数はすべての行で同じままなので、2つをループする必要があります乗数結果変数 。 さらに、ループには2つの範囲が必要です。 最初の範囲は異なる行に対応する乗数のリストを保持しますが、2番目の範囲は結果値を保持します。

まず、先に進んで printMultiplicationTable()関数を記述しましょう。

fun printMultiplicationTable(factor: Int, start: Int, end: Int) {
    val multipliers = start..end
    val multiplicationResults = factor * start..factor * end step factor
    for ((multiplier, result) in multipliers zip multiplicationResults)
        println("$factor x $multiplier = $result")
}

次に、multiplicationResultsは実際にはprogressionであり、ステップ値はfactorに等しいことに注意してください。

最後に、この関数を検証して、3で始まり7で終わる行の27の掛け算の九九を表示しましょう。

printMultiplicationTable(27, 3, 7)

コンソールに表示される出力は期待どおりであることがわかります。

27 x 3 = 81
27 x 4 = 108
27 x 5 = 135
27 x 6 = 162
27 x 7 = 189

8. 結論

このチュートリアルでは、Kotlinでサポートされているさまざまなループについて説明しました。 まず、ループステートメントの中で最も単純な repeat、を確認しました。 次に、 for ループと、それを使用して範囲、配列、およびコレクションを反復処理する方法を確認しました。 次に、whileループとdo..whileループ、およびそれらの微妙な違いを確認しました。

さらに、理解を複数の変数を使用したループに拡張しました。 最後に、Kotlinの構造的なジャンプ式である return break 、およびcontinueを確認しました。

いつものように、ソースコードはGitHubから入手できます。