Caution

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

  1. トップページ
  2. Swift入門編 - for-in文と範囲演算子について

for-in文と範囲演算子について

みなさまどうも。

さて、続きまして『for-in文』(フォーインぶん)と『範囲演算子』ってやつをやっていきましょう。

というわけでいきなりですがサンプルをどん。

let a = [0, 1, 2]

for i in a {
    print(i)
}

これが『for-in文』になります。実行結果はこんな感じです。

0
1
2

配列『a』の個数だけループが行われていますね。このように『for-in文』はループ処理を行うための構文になります。

というわけで文法から細かくみていきましょう。

まず『for』と記述し、その隣に任意の識別子を記述してあげます。上記の場合だと『i』が該当しますね。この識別子についてはSwiftの識別子として使用できる名前ならなんでもOKです。

ここでちょっと注意点ですが、この識別子は定数として扱われます。なので『let』で宣言した識別子と同じ扱いになるので以下のように『i』を上書きすることはできません。

let a = [0, 1, 2]

for i in a {
    i = 100 // この『i』は定数なので上書きすることはできません。
    print(i)
}

ちなみに『for』の後に『let』とか『var』とかを記述することはできません。ここも間違いやすいので気をつけて下さい。

let a = [0, 1, 2]

for let i in a { // 『for』の後に『let』とか『var』とか記述することはNGです。
    print(i)
}

そんでもって適当な識別子を記述したら『in』と記述します。そして『in』の隣に配列とか辞書とかを記述してあげます。この要素の数だけループが行われる形になりますね。そしたら『{}』を書いて、その中に行いたい処理を記述してあげればOKです。

let a = [0, 1, 2]

for i in a { // 配列『a』の個数分だけループします。
    print(i) // こんな感じで『{}』の中に行いたい処理を書きます。
}

基本的な文法はこんな感じです。では続きまして『for』のとなりに記述した定数に何が入るのか確認していきましょう。

まず配列でループさせた場合ですね。配列で『for-in文』を行った場合はループごとの各要素が定数に収まる形になります。

let a = [0, 1, 2]

for i in a {
    print(i)
}
0
1
2

続いて辞書でループさせた場合です。辞書でループさせる場合はちょっと勝手が違うのでそれも合わせて確認していきましょう。辞書でループさせるとなるとこんな感じの記述になります。

let d = [
    "初音ミク": "080xxxxyyyy",
    "Lily": "090xxxxyyyy",
]

for t in d {
    print(t)
}

これの実行結果はこうなります。

("Lily", "090xxxxyyyy")
("初音ミク", "080xxxxyyyy")

なにやら『()』の中にキーと値が収まってるみたいですね。さて、この『()』は何の『()』かというとタプルの『()』になります。つまり、辞書で『for-in文』を使用した場合の定数にはタプルが収まるということになります。

※タプルについてはこちらへどうぞ

なので上記の場合でそれぞれのキーと値を出力するとなるとこのような記述になります。

let d = [
    "初音ミク": "080xxxxyyyy",
    "Lily": "090xxxxyyyy",
]

for t in d {
    print(t.0) // キーが出力されます。
    print(t.1) // 値が出力されます。
}

『定数名.0』と『定数名.1』を記述しているところがミソですね。

しかし、上記のように『定数名.0』と『定数名.1』という記述だと何の値にアクセスしてるのかちょっと分かりづらい感じがありますよね。なので辞書でループさせる場合は以下のようにするのが一般的です。

let d = [
    "初音ミク": "080xxxxyyyy",
    "Lily": "090xxxxyyyy",
]

for (key, val) in d {
    print(key) // キーが出力されます。
    print(val) // 値が出力されます。
}

『for-in文』の定数を記述するところにタプル『(key, val)』が記述されていますね。このように辞書でループさせる場合はタプルで受け取ってしまうようにした方が分かりやすくなるのでオススメです。ちなみにタプルの最初の要素にキーが、最後の要素に値(バリュー)が入る形になりますので間違えないようにして下さい。

『for-in文』と同じようにループ処理を行える『for文』っていうのがいます。以下のやつですね。

for var i = 0; i < 10; ++i {
    // ここに処理かくよー
}

C言語の時代から存在してる構文なので古い時代からプログラミングを行っている方はかなり使い込んできた印象になるかと思います。

さて、この『for文』ですが最新のSwiftでは完全に使えなくなりました。昔は使えたんですけど今は完全にダメです。ちょっとさみしいですけどこれが現実です。

なのでループ処理を行う場合は全て『for-in文』を使用するようにして下さい。

さて、ではちょっとだけ応用技のご紹介です。配列や辞書でループ処理を行った場合に「今が何回目のループなのかが知りたい」といった場合もあると思います。

そういう場合は以下のようにしてみましょう。

let d = [
    "初音ミク": "080xxxxyyyy",
    "Lily": "090xxxxyyyy",
]

var i = 0 // 何回目のループなのか管理するための変数を定義します。初期値は『0』です。

for (key, val) in d {
    print(i) // 今が何回目のループなのか出力します。

    print(key) // キーが出力されます。
    print(val) // 値が出力されます。

    i = i + 1 // ループ処理が行われるごとに『1』が加算されるようにしてあげます。
}

『for-in文』の外側でInt型の変数を定義して、ループ処理の内部で『1』を加算してあげるのがミソですね。このパターンは良く使用されるので覚えておくと良いかもしれません。あとSwiftでは『++i』といったようなデクリメントは非推薦になってますのでご注意です。

さて、続いてこれまでと違うパターンの『for-in文』についてやっていきます。これまで紹介した『for-in文』のサンプルを振り返ってみると配列や辞書を元にしたループ処理ばっかりでしたね。

では「任意の回数だけループさせたい」という場合はどうするのか、というとこうなります。

for i in 0...2 {
    print(i)
}

実行結果は以下です。

0
1
2

計3回のループが行われていますね。

上記の『in』の隣に記述してある『0...2』の『...』という部分に注目です。これは『範囲演算子』と呼ばれるもので、上記のように『0...2』と記述した場合は『0』と『1』と『2』のループが行われます。

なので「100回ループ処理を行いたいぜ!」といった場合はこうなります。

for i in 0...99 { // 計100回ループさせます。
    print(i)
}

ちょっと注意点ですが『0』から数え始めているので100回実行させるとなると『0...99』になります。ここ、間違いやすいので注意です。

そしてもういっちょ『...』と同じ『範囲演算子』の『..<』ってやつがいますのでこいつも紹介しておきます。使い方はほとんど同じなんですが『...』と違って最後の数値を含まない、という違いがあります。ちょいと以下のサンプルをみてみましょう。

for i in 0..<2 {
    print(i)
}

先程のサンプルの『...』を『..<』に変えてみました。実行結果はこうなります。

0
1

先ほどと違って最後の『2』が出力されていませんね。このように『..<』を使用すると最後の数値を含まない範囲となります。

数値『a』と数値『b』で説明するならば『a...b』とすると数値『a』以上で数値『b』以下の範囲、『a..<b』とすると数値『a』以上で数値『b』未満の範囲になりますね。

ちなみに『...』は『閉範囲演算子』、『..<』は『半開範囲演算子』って呼ばれることもありますが、これについてはあんまり使われないので覚えなくても大丈夫な気がします。

では続きまして『範囲演算子』を記述する際の注意点を確認しておきましょう。まず『範囲演算子』を使用した際のオペランドは整数じゃないとNGになります。

for i in 0...2.0 { // これはエラーです。
    print(i)
}

整数ならOKなので負の数値はOKです。

for i in -2...2 { // これはOKです。
    print(i)
}

あと数値『a』と数値『b』とした場合に『a <= b』というのが成り立っていないとエラーになります。

for i in 3...2 { // これはエラーです。
    print(i)
}

for i in 3..<3 { // 同じ数値ならばOKです。
    print(i)
}

for i in 3..<3 { // 同じ数値ならばOKです。
    print(i)
}

そして上記のことを満たすならば『範囲演算子』のオペランドに定数や変数を使ってもOKです。

let n = 1, _n = 3

for i in n..._n {
    print(i)
}

『範囲演算子』の注意点はこんな感じになりますね。『for-in文』とセットで使われることが多いのでバッチリマスターしちゃって下さい。

『for-in文』でループをさせるときに『for』のとなりに書く定数を内部の処理で使わないといった場合があります。

例えば以下のような感じですね。

let a = [0, 1, 2]

for i in a {
    print("初音ミクちゃんが大好きです")
}

上記の処理だと『for-in文』で定義した定数『i』を全く使っていませんね。このような場合は『_』を使ってあげると尚良い感じになります。

let a = [0, 1, 2]

for _ in a { // このように処理の内部で定数を使用しない場合は『_』を使ってあげると尚良しです。
    print("初音ミクちゃんが大好きです")
}

ループ処理をさせる際にループの元になっているデータを使用しない、といったパターンはかなりあります。そういう時は上記のように『_』を使ってしまって下さい。

というわけで『for-in文』と『範囲演算子』については以上になります。続いての記事では『while文』と『do-while文』についてやっていきましょう。ではではこの辺で失礼致します。

この記事は桜舞が執筆致しました。

著者が愛する小型哺乳類

桜舞 春人 Sakurama Haruto

ISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。

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