Swiftでwhileを使って上手に繰り返し処理を行おう

Swiftのループ文で使用するコードには主にforとwhileがあります。使用頻度的にはfor文の方がよく使うかと思いますが、while文も単純なループには使えます。そこでこのページでは、while文でのループについて解説します。

while文のサンプルコード

while文の構造はシンプルなので、さっそくサンプルコードを紹介します。

var i = 0
while i < 4 {
print(i)
i += 1
}
// 0 1 2 3

Swiftのループは他のプログラミング言語よりもさらにシンプルで、whileの後ろに直接条件を書くだけです。条件を満たす間はループが回り続け、条件を満たさなくなったらループを抜けます。

また、無限ループにすることもできます。具体的には以下のように記述します。

var i = 0
while true {
print(i)
i += 1
}

何がtrueというわけではなく、Swiftのboolean型はデフォルトでtrueになっています。つまり何かfalseに変更するような処理を記述しない限り永遠にtrueを満たすことになります。

このようにtrueの性質を活かせばwhile文で無限ループを記述できるのですが、これを実行すると当然落ちてしまいます。メモリの限界値に達するまで高速で処理を繰り返すことになるため、無限ループは落ちる以外に選択肢がないのです。

なので無限ループは実際の開発に適さないのですが、例外もあります。それは、無限ループを指定しておいて、処理のなかでbreakさせるパターンです。whileの条件に指定しておけば良いのですが、条件が長くなる場合などはあえて条件をtrueにしておいて、while文のなかでbreakするための条件を記述することができます。

その場合はだいたいwhile文のなかにif文を書いて、if文に当てはまる場合は処理を実行、elseに入ったらbreakさせる、といった書き方をします。サンプルコードを見てみましょう。

var i = 0
while true {
i += 1
if 4 < i {
break
}
if i == 2 {
continue
}
print(i)
}
// 1 3 4

このサンプルコードでは2のときは処理を飛ばして、4より大きくなったらbreakさせています。厳密に覚えておく必要はないのですが、4で処理が行われるかどうかという問題があります。

数学の範疇ではありますが、4 < 4はfalseなので4の場合処理が実行されます。次にループが回ってきたら条件判定の前にiを加算しているので、出力コードの前にbreakします。つまり、iが5になった次の上でif文の条件に当てはまってbreakします。

ちなみに、while文をfalseにすると処理は100%実行されます。具体的には以下のようなことです。

while false {
print("実行されました!")
}

repeat-while文を使用する

while文の使い方は上記の通りですが、Swiftにはrepeat-while文というものがあります。使い方は以下のようになります。

repeat {
print("実行されました!")
} while false

上記のサンプルコードを実行すると、一度だけ「実行されました!」と出力されます。理由としては、repeat文に入って処理を実行した後にwhile文の条件判定が行われ、falseで終了するからです。

repeat-while文はwhileの条件式を後ろに持ってくるために存在します。処理を実行してから条件判定するということです。

for-in文を使用する

while文、repeat-while文の使い方を紹介してきましたが、実際のところfor-in文の方が利便性が高く開発現場でもよく使われます。構文は以下です。

for 定数 in 式 {
// 繰り返し実行されるコード
}

この構文を使用したサンプルコードは以下です。

var total = 0
for count in 0...10 {
total += count
}
print(total) // => 55 と表示

なぜwhile文やrepeat-while文よりもfor-in文が使われるかというと、定数を宣言しなくて良いからです。たとえばwhile文やrepeat-while文でカウンタを用意する場合、前に宣言しておく必要があります。

for-in文ならforの後ろに定数を書けるので、先に宣言しておく必要がありません。またinの後ろの条件指定も…で範囲指定できるため、コードが短くシンプルに済むのです。以上のことから、for-in文で記述できるコードはfor-in文で記述した方が良いでしょう。

逆にカウントではなくたとえば変数の中身や外部のメソッドで条件判定を行う場合、while文などで条件判定した方が記述しやすいです。カウント系の条件判定はfor-in文がベストな場合が多いです。

ループのネスト

while文でもrepeat-while文でもfor-in文でも同じですが、ループのなかにさらにループを作ることができます。これをループのネストと呼びます。他のプログラミング言語経験のある方はわかるかと思いますが、世の中のほとんどのシステムでループのネストが使われていると言っても過言ではありません。

なので、ループをネストさせる考え方は必ず押さえておく必要があります。ただしそれほど難しいものではなく、以下のように記述します。

//外側のループ(行き止まりまで進む)
while !isBlocked {
while !isOnGem {
moveForward()
} //内側のループここまで
collectGem()
turnLeft()
} //外側のループここまで

外側のループのなかで内側のループを回し、内側のループが回り終わると再度外側のループに入ります。さらに内側のループに入り、内側のループが終わったら外側のループに戻るという流れです。

そして階層を深めていくと、二重ループだけでなく三重、四重と増やしていくことが可能です。あまり設計を考えずに実装するとループのネストは深くなりすぎる傾向にあり、どちらかというとネストしすぎないように注意する必要があります。

まずはループのプログラミングに慣れてそこからネスト構造を作る練習もした方が良いのですが、ある程度慣れてきたらなるべくネストは三重くらいまでにして、その他の方法でプログラミングするようにした方が良いでしょう。

たまに六重くらいのネストを見ることがありますが、良いソースコードとは言えません。インデントも右に大きくずれることになり、単純に処理がどうなっているのか他人が見てわかりにくいです。

ソースコードは基本的に他人が見てわかりやすいことが重要で、複雑なロジックをなるべく単純明快に書くのが良いプログラミングと言えます。あえてわかりにくい書き方をする人もいますが、開発現場ではNGなことが多いです。

そしてループ処理はソースコードがわかりやすくなるかどうかに大きく関係しており、ループのネストが深くなりすぎると明らかに可読性が下がります。ネストが深くなりそうなときは深くならないように分割する方法を考えることが重要で、それがループ処理の醍醐味と言っても過言ではないかもしれません。

まずループ処理で効率化できないか、ネストが深くなりすぎたらどうすれば分割して読みやすくできるか、といったことを考えるとうまくループ処理を使いこなせます。

▼Swift関連の記事一覧
1, 【Swiftのフリーランス案件情報付き】仕事やエンジニアの将来性・学習方法!
2, 繰り返し処理に使えるSwiftのfor文とfor-in文の便利な使い方まとめ
3, 条件分岐に便利なSwiftのSwitch文の使い方まとめ
4, アプリ開発でよく使うSwiftの4つの文法を解説します
5, Swiftのoptional型を使いこなすための7つのポイント
6, Swiftで文字列を扱うためのstring型の使い方
7, Swiftでの配列の宣言・初期化・代入・参照の方法まとめ
8, 実際の開発現場でのSwiftの変数・定数の使われ方を解説します
9, Swiftでif let文を使って出来ることとguard letの使い分けに関して
10, 開発現場でよく使うSwiftのif文の条件分岐をまとめました
11, SwiftにおけるTupleの使い方とわかりやすく解説します
12, 初心者にオススメのSwiftのサンプルコードをまとめてみました
13, SwiftのString、Int、Doubleの型の変換方法をまとめました
14, 開発現場で役に立つSwiftのクロージャの使い方
15,(この記事)Swiftでwhileを使って上手に繰り返し処理を行おう
16, Swiftで文字列の長さをチェックするのにlengthを使ってみよう
17, Swiftのdictionaryの使い方と初期化方法をまとめました
18, Swiftの値渡しと参照渡しに関するまとめ
19, Swiftで参照渡ししたい時のinoutの便利な使い方
20, Swiftでfor-in文でindexを使いたい時の方法まとめ
21, Swiftでのクラスとstruct(構造体)の使い分けを解説します

人気記事

編集部おすすめ記事

この記事を読んだ人はこんな記事を読んでいます