※ カリキュラムでは、Cloud9のターミナルやエディタを利用します。
まだ用意していない方は「AWS Cloud9を準備しよう」を参考に導入してください。
繰り返しについて理解しよう
すでに「基本的な制御構造」の条件分岐について学んでいましたよね。
今回は図の1番右に位置する「反復構造(繰り返し)」について学びます。
繰り返しとは
繰り返しとは、プログラムの中である条件が成り立つか、もしくは成り立たないかによって、特定の箇所を繰り返し実行させることです。
以下のフローチャートでは、条件が成り立つときはYesの矢印の先に進み「処理①」を実行します。条件が成り立たないときは、Noの矢印の先に進み処理を終了します。
条件が成り立つ間、Yesの矢印に進み「処理①」は繰り返されます。
条件が成り立たない場合にも、処理を繰り返し実行させることもできます。
以下のフローチャートでは、条件が成り立つときはYesの矢印の先に進み処理を終了します。条件が成り立たないときは、Noの矢印の先に進み「処理①」を実行します。
条件が成り立たない間、Noの矢印に進み「処理①」は繰り返されます。
今回は「条件が成り立つ間、一定の処理を繰り返す」という前者の方で説明します。
「条件分岐」は条件で処理を切り替えていたけど、「繰り返し」は条件で同じ処理を実行させることができるんだね!
その通り!次は具体的な例をあげて説明するね
繰り返しの具体例
具体的な例として、「0から9の数字を順番に出力する」で考えてみましょう。
繰り返したい処理は「数字を出力する」で、いつまで繰り返すかの条件は「数字が9以下の間」になります。
この手順をフローチャートにすると、以下のように記述することができます。
数字の初期化後に「数字が9以下」という条件が成り立てば、Yesの矢印に進み「数字」を出力します。そして、次の処理で数字に1を足してから条件に戻ります。
1回目の処理の時の数字は、以下の通りです。
最初の数字は0なので、「数字が9以下」という条件は成り立ちます。Yesの矢印に進むので、0が出力されます。そして、0に1が足されます。この時点で数字は1になります。
そのまま条件に戻りますが、2回目の処理の時の数字は0ではなく1として扱われます。
「数字が9以下」という条件が成立する間は、数字の出力後に1が足され続けます。
そのため、0から9の数字を順番に出力することができます。
数字が10になると条件は成立しないので、Noの矢印に進み処理を終了します。
Rubyでは、繰り返し処理を効率的に行える制御構造がいくつか用意されています。その中でも代表的なwhile
について学んでいきます。
whileの基本的な使い方を学ぼう
while
を使うと、条件が成り立つ間は一定の処理を繰り返すことができます。
それでは実際にサンプルコードを使いながらwhile
の基本的な使い方を学び、繰り返しについて理解を深めていきましょう。
whileの基本構文
while
の基本的な書き方は、以下の通りです。
1
2
3
while 条件式 do
# 条件式が真である間に繰り返したい処理
end
条件式には「比較演算子」などを使って、いつまで繰り返すかの条件を指定し、do
~end
内には、条件が成立するまでの間に繰り返したい処理を指定します。
if
の章では「真偽値」について学びましたが、while
では条件式が評価されて「真」であれば処理が繰り返し実行されます。
真偽値を復習したい方は、「条件式の評価」を参考にしてください。
whileを使ってみよう
実際にwhile
を使って処理を繰り返してみましょう。
ここからは、Rubyのファイルを使います。
while.rb
という名前のファイルを「pikawakaフォルダ」の直下に作成しましょう。
前述の具体例で挙げたフローチャートの処理手順をソースコードにします。
数字にはcount
という変数を使います。
上のフローチャートのソースコードは、以下の通りです。
以下のソースコードをwhile.rb
に書き、rubyコマンドで実行してみましょう。
1
2
3
4
5
6
count = 0
while count <= 9 do
p count
count += 1
end
実行すると、動画のように0
から9
まで順番に数字が出力されます。
このプログラムがどのように出力されているのかを確認してみます。
whileの使い方を確認してみよう
先ほど実行したwhile.rb
の内容でwhile
の使い方を確認してみます。
フローチャートを使いながら、コメントアウトに記載する1~3の順番で説明します。
1
2
3
4
5
6
count = 0 # 1.変数を初期化する
while count <= 9 do # 2.条件を指定する
p count # 3.繰り返したい処理を記述する
count += 1 # 変数の値を更新する
end
1.変数を初期化する
まずは、数字を0で初期化します。
数字には変数count
を使います。
初期化とは、宣言した変数に初期値を書き込むことなのでcount
に0
を代入します。
Rubyでは、最初の代入が変数の宣言になります。
1
count = 0
2.条件を指定する
次に「数字は9以下か」という条件を指定します。
「9以下」は9も含まれるので、比較演算子の<=
を使います。
while
の後に条件式count <= 9
を書くことで「countが9以下になるまで繰り返す」という条件が設定できます。
1
2
3
count = 0
while count <= 9 do
左辺にcount
、右辺に9
を置きます。反対にすると違う意味になるので気をつけましょう。
3.繰り返したい処理を書く
最後に条件が成立するまで繰り返したい処理を書きます。
繰り返したい処理は、do
~end
内に書きます。
pメソッドを使って数字であるcount
を出力させます。
次に数字に1を足したいので、自己代入演算子の+=
でcount
に1を足して代入します。
1
2
3
4
5
6
count = 0
while count <= 9 do
p count
count += 1 # count = count + 1 と同等
end
count += 1
によって、count
の値を1ずつ足して更新することができます。
これにより、数字を0から9まで順番に出力できます。
処理の流れを確認してみよう
続いて、処理の流れを確認してみます。
繰り返し処理の流れについては、冒頭の「繰り返しの具体例」で少し触れましたが、今回はフローチャートだけではなく、コードと共に説明します。
1
2
3
4
5
6
count = 0
while count <= 9 do
p count
count += 1
end
処理の流れを把握している方は、次のwhileの注意点に進みましょう。
1回目の処理の流れ
最初にcount
を0
で初期化しているので、途中まで数字は0
です。
条件の「数字は9以下か」は成立し、do
~end
内の処理が上から順番に実行されます。
まずp count
によって、0
が出力されます。
続いて、以下のようにcount
の値が0
から1
に更新されます。
count
の値は0
だったので、0 + 1
で1
になります。
「2回目の処理の流れ」に入る前に、数字は1に更新されている所がポイントです。
2回目の処理の流れ
「1回目の処理」が終わると、再び条件に戻ります。
この時点での数字は1
なので、条件の「数字は9以下か」は成立します。
続いてp count
が実行されますが、count
は1
なので1
が出力されます。
次の「3回目の処理」に入る前には、以下のように数字が2
に更新されます。
このようなdo
~end
内の処理は「数字が9以下の間」に繰り返し実行されます。
以下のように数字(count
)が10
になった時点で、「数字が9以下か」という条件は成立しなくなるので、while
の処理を終了します。
whileの注意点(無限ループ)
whileの注意点として、無限ループにならないように注意する必要があります。
無限ループとは、一連の処理が永遠に繰り返されることです。「条件式の結果が変わらないコード」や「条件式を間違える」と無限ループになる恐れがあります。
while.rb
では変数の値を更新させる処理を忘れてしまうと、無限ループになります。
1
2
3
4
5
6
count = 0
while count <= 9 do
p count
count += 1
end
以下のようにcount += 1
を削除すると、count
はずっと0
の状態になります。
1
2
3
4
5
count = 0
while count <= 9 do
p count
end
そのためcount <= 9
は真を返し続ける、つまり条件は成立し続けてしまうので、動画のように永遠と0が出力されます。
このような場合は、以下のようにターミナルでプログラムを強制終了(Control+Cキー)させる必要があります。
無限ループはコンピュータに負荷がかかるので、阻止する必要があります。
while
を使う際には「条件式が偽になるか」など繰り返しが終わる必要があることを念頭におきましょう。
繰り返しの制御
Rubyには、繰り返し処理用の制御構造がいくつか用意されます。
その中でもよく使われる「break」と「next」の使い方を説明します。
breakやnextなどを使うことで、繰り返し処理の動きを変えることができます。
break
breakは、whileなどの繰り返し処理から脱出することができます。
以下のようにwhile.rb
にbreak
を書き、rubyコマンドで実行してみましょう。
1
2
3
4
5
6
7
count = 0
while count <= 9 do
p count
count += 1
break
end
これまでは0
から9
まで順番に出力されていましたが、break
を入れることで動画のように0
だけが出力されます。
1回目の処理でwhile
を脱出しています。
またbreak
のあとに他のコードを記述しても、実行されずにwhile
を脱出します。
以下のようにbreak
のあとにp count
を書き、rubyコマンドで実行してみましょう。
1
2
3
4
5
6
7
8
count = 0
while count <= 9 do
p count
count += 1
break
p count # 1の出力を期待
end
count += 1
によって、count
の値が0
から1
に更新されているので、最後のp count
では1
を出力することを期待しています。
しかし、動画のようにbreak
の後にあるコードは実行されず、0
だけが出力されます。
next
nextは、現在の繰り返し処理を途中で中断し、次の繰り返しに移動することができます。
以下のハイライト箇所をwhile.rb
に書き、rubyコマンドで実行してみましょう。
1
2
3
4
5
6
7
8
9
10
count = 0
while count <= 9 do
if count == 3 then
count += 1
next
end
p count
count += 1
end
count
の値が3
の場合、count
の値を出力せずに更新だけします。そして、next
によって繰り返し処理を中断して、次の処理に移動させます。
そのため、動画のように3
を抜かした数字を順番に出力します。
このようにnext
はifと使うことで、特定の条件の時に現在の繰り返し処理を中断し、次の繰り返しに移動することができます。
ブロック付きメソッド(イテレータ)
繰り返しの制御構造ではありませんが、ブロックを活用するメソッド(ブロック付きメソッド)では繰り返し処理を簡潔に書くことができます。
その中でも代表的な「timesメソッド」と「eachメソッド」を簡単に説明します。
timesメソッド
timesメソッドは、指定した回数だけdo
~end
内の処理を繰り返します。
1
2
3
繰り返したい回数.times do
#繰り返したい処理
end
例えば"こんにちわ、ぴっかちゃん"
と3回出力させる場合は、以下のように書きます。
1
2
3
4
5
6
7
8
9
10
count = 3
count.times do
p "こんにちわ、ぴっかちゃん"
end
#上記の出力結果
"こんにちわ、ぴっかちゃん"
"こんにちわ、ぴっかちゃん"
"こんにちわ、ぴっかちゃん"
timesメソッドは、処理を繰り返す回数が明確に決まっているときに便利です。
ブロックの変数を使う場合は、以下のようにブロック変数i
には0
からcount -1
の数値が渡されます。
1
2
3
4
5
6
7
8
9
10
count = 3
count.times do |i| # iには0からcount -1 の数値が順番に渡される
p i
end
#上記の出力結果
0
1
2
count
には数値の3
が代入されているので、count - 1
は3 - 1
で2
です。
つまり上記の処理を実行すると、0
から2
までの数値が出力されます。
eachメソッド
eachメソッドは「配列」や「ハッシュ」の時に学びましたね。
要素分の処理を繰り返してくれるので、値を出力させたいときに便利です。
1
2
3
4
5
6
7
8
9
10
countries = ["Japan", "France", "Brazil"]
countries.each do |country|
p country
end
#上記の出力結果
"Japan"
"France"
"Brazil"
1
2
3
4
5
6
7
8
9
10
user = { name: "田中 太郎", age: 18, gender: "男" }
user.each do |key, value|
p "キーは#{key}で、値は#{value}です。"
end
#上記の出力結果
"キーはnameで、値は田中 太郎です。"
"キーはageで、値は18です。"
"キーはgenderで、値は男です
その他のメソッド
ブロック付きメソッドには、整数オブジェクトから指定した回数まで1ずつ増やして処理を繰り返すuptoメソッドや、整数オブジェクトから指定した回数まで1ずつ減らして処理を繰り返すdowntoメソッドがあります。
1
2
3
整数オブジェクト.upto(指定した回数) do |変数|
# 繰り返しの処理
end
1
2
3
整数オブジェクト.downto(min) do |変数|
# 繰り返しの処理
end
状況に応じて適切なメソッドを使えるように、使い方を覚えておきましょう。
以下の表のリンク先で、ブロック付きメソッドの詳しい使い方を確認しましょう。
ブロック付きメソッド | 説明 |
---|---|
times | 指定した回数繰り返し処理を行う |
eachの使い方 | 要素の数だけ繰り返し処理を行う |
uptoの使い方 | 整数オブジェクトから指定した回数まで1ずつ増やして繰り返し処理を行う |
downtoの使い方 | 整数オブジェクトから指定した回数まで1ずつ減らして繰り返し処理を行う |
繰り返しの制御構造
Rubyの繰り返しの制御構造には、while
だけではなくuntil
やfor
があります。
until
やfor
の使い方については、以下の表のリンク先を参考にしてみてください。
条件分岐 | 説明 | リンク |
---|---|---|
while | 条件式の結果が真のとき繰り返される | |
until | 条件式の結果が偽のとき繰り返される | untilの使い方 |
for | オブジェクトの要素分繰り返される | forの使い方 |
この記事のまとめ
- 繰り返しとは、プログラムの中である条件が成り立つか、もしくは成り立たないかによって、特定の箇所を繰り返し実行させること
- プログラムの中で特定の箇所を何度も繰り返すことを「ループ」とも呼ぶ
- 一連の処理が永遠に繰り返される「無限ループ」に注意しよう!
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します