Swift 文法その5 - ループ処理 -

同じ処理を指定回数繰り返します。for、forEach、while の3つの書き方があります。

for

ループ回数を指定する

// 3回ループする場合
for i in 1...3 {
    print(i) // 1, 2, 3
}

// または
for i in 1..<4 {
    print(i) // 1, 2, 3
}

「1...3」は「1から3まで」の意味で、i には順番に「1」「2」「3」という値が入り、今何回目のループなのかがわかります。「1..<4」は「1から4未満まで」という意味なので同じく「1」「2」「3」の3回ループします。

配列をループ

let a = [1, 2, 3]
for value in a {
    print(value) // 1, 2, 3
}

// インデックス付き
for (i, value) in a.enumerated() {
    print(i) // 0, 1, 2
    print(value) // 1, 2, 3
}

// nil 以外の要素をループ
let a: [String?] = ["1", nil, "2"]
for case let value? in a {
    print(value) // "1", "2"
}

配列の要素を順番に取り出して処理します。2番目はインデックス(要素番号)を知りたい場合の書き方で、最後のは配列の中に nil が含まれている可能性があり、その nil はループさせたくない場合の書き方です。

文字列をループ

let a = "abc"
for char in a {
    print(char) // "a", "b", "c"
}

文字列を1文字ずつ取り出します。

辞書をループ

let a = ["a": 100, "b": 200, "c": 300]
for (key, value) in a {
    print(key) // "a", "b", "c"
    print(value) // 100, 200, 300
}

key / value を取り出します。(辞書についての記事でも触れましたが、ループの際に順番は保証されないので、上記の例のように "a", "b", "c" と毎回出力されるわけではないのでご注意ください)

forEach

配列または辞書をループさせる時に使用します。できることは for 文と同じです。配列の forEach では要素を「$0」という略式の書き方で参照できます。

let a = [1, 2, 3]

// 略式
a.forEach { print($0) } // 1, 2, 3

// 名前を指定して参照する場合
a.forEach { value in print(value) } // 1, 2, 3

// 辞書
let b = ["a": 100, "b": 200]
b.forEach { (key: String, value: Int) in
   print(key) // "a", "b"
   print(value) // 100, 200
}

while

指定した条件を満たさなくなるまでループします。for や forEach があらかじめループ回数が決まっているのに対し、こちらは任意のタイミングで処理を中断してループをやめる書き方です。

var a = 0
while a < 2 {
    print(a) // 0, 1
    a += 1
}

上記の例だと、whileの条件式は「a が 2以下だったらループを続ける」という意味になり、毎回の処理の最後で a に 1 を足しているので3回目のループで2 以上になり、そこでループが中断するので結果として2回ループする、ということになります。

また、処理を中断する方法として break を書く方法もあります。

var a = 0
while true {
    if a >= 2 {
        break 
    }
    print(a) // 0, 1
    a += 1
}

while の条件式に true を指定すると、break するまで常にループし続ける、という意味になります。break は「 a が 2以上」の場合に通るので、3回目のループの途中で処理を中断します。ちなみに、break は for 文でも使えますが、forEach 文では使用できないのでご注意を。

また、break の他に処理を中断する方法として、continue というものがあります。continue が出てきた時点でその下に続く処理を実行しないのは break と同じですが、ループ自体は終わらず、次のループを開始する、という違いがあります。

for i in 1...3 {
    if i == 2 {
        continue
    }
    print(i) // 1, 3
}

i が 2 の場合はその下に書かれている print 文は通りませんが、そのまま 3 回目のループが開始されるので、3回目の時には print 文が実行されます。

応用(ループの入れ子)

最後に、もしかしたら使うかもということで、ループの中に違うループがある場合についてご紹介します。

for i in 1...3 {
    print(i)
    for j in ["a", "b", "c"] {
        print(j)
    }
}

まず、上記の挙動を確認すると、i の「1 」が出力されて、その後、2つ目のループ処理が走り "a", "b", "c"  と出力されます。そして次に「2」が出力されてまた  "a", "b", "c" と出力される、という流れになります。

では、2つ目のループに break を入れてみます。

for i in 1...3 {
    print(i)
    for j in ["a", "b", "c"] {
        if j == "b" { 
            break 
        }
        print(j)  
    }
}

出力結果は「1, "a", 2, "a", 3, "a"」となり、2つ目のループは "b" が出てきた時点でループが終わるので、1回しかprint 文が実行されません。また、ループが中断するのは今実行中のブロックのループのみで、その上のループは関係なく続きます。

それではここから応用ですが、上記で "b" が出てきた時点でその上のループも中断させる場合、「ラベル」をつけて、そのラベルを指定して break する、という方法があります。

a:for i in 1...3 {
   print(i)
   b:for j in ["a", "b", "c"] {
       if j == "b" { 
           break a
       }
       print(j)
   }
}

for 文の前に「ラベル名:」をつけることでループ文に名前をつけることができます。上記の例では1つ目のループに「a」、2つ目のループに「b」というシンプルな名前をつけています。そして、break するときに a というラベルを指定すると、a のループを終わらせる、ということになるので、出力結果としては「1, "a"」のみとなります。

ただ、あまり使う機会はないと思われるので、こういうこともできる、ということだけ覚えておいて、必要になったらまたこの記事をご参照いただければと思います。

おさらい

配列や辞書をループさせる時は for 文と forEach 文の2通りありますが、個人的には for 文を採用することが多いです。本文中に break は forEach では使えない、と書きましたが、同じく continue も使用できません。ただし、forEach で return と書くと実は continue と同じ効果があるのですが、覚えるのが複雑になるので素直に for 文で良いと思います。

ただ、ご紹介するのは先になると思いますが SwiftUI では画面のリスト表示に forEach を使う場面がよく出てくるので、forEach でもループ処理が書ける、ということだけ念頭において頂ければと思います。

次は「クラス」についてご紹介します。

この記事が気に入ったらサポートをしてみませんか?