すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Rails

【Rails】 7.Rubyの繰り返しを学ぼう

※ カリキュラムでは、Cloud9のターミナルやエディタを利用します。
まだ用意していない方は「AWS Cloud9を準備しよう」を参考に導入してください。

繰り返しについて理解しよう

前回は「基本的な制御構造」の条件分岐について学びましたね。
今回は図の1番右に位置する「反復構造(繰り返し)」について学びます。

基本的な制御構造

繰り返しとは

繰り返しとは、プログラムの中である条件が成り立つか、もしくは成り立たないかによって、特定の箇所を繰り返し実行させることです。

以下のフローチャートでは、条件が成り立つときはYesの矢印の先に進み「処理①」を実行します。条件が成り立たないときは、Noの矢印の先に進み処理を終了します。

条件が成り立つ間、Yesの矢印に進み「処理①」は繰り返されます。

ループ1

条件が成り立たない場合にも、処理を繰り返し実行させることもできます。

以下のフローチャートでは、条件が成り立つときはYesの矢印の先に進み処理を終了します。条件が成り立たないときは、Noの矢印の先に進み「処理①」を実行します。

ループ2

条件が成り立たない間、Noの矢印に進み「処理①」は繰り返されます。

今回は「条件が成り立つ間、一定の処理を繰り返す」という前者の方で説明します。

ぴっかちゃん

「条件分岐」は条件で処理を切り替えていたけど、「繰り返し」は条件で同じ処理を実行させることができるんだね!

その通り!次は具体的な例をあげて説明するね

ぴかわかさん

繰り返しの具体例

具体的な例として、「0から9の数字を順番に出力する」で考えてみましょう。

繰り返したい処理は「数字を出力する」で、いつまで繰り返すかの条件は「数字が9以下の間」になります。

この手順をフローチャートにすると、以下のように記述することができます。

フローチャート3

数字の初期化後に「数字が9以下」という条件が成り立てば、Yesの矢印に進み「数字」を出力します。そして、次の処理で数字に1を足してから条件に戻ります。

1回目の処理の時の数字は、以下の通りです。

フローチャート4

最初の数字は0なので、「数字が9以下」という条件は成り立ちます。Yesの矢印に進むので、0が出力されます。そして、0に1が足されます。この時点で数字は1になります。

そのまま条件に戻りますが、2回目の処理の時の数字は0ではなく1として扱われます。

フローチャート5

「数字が9以下」という条件が成立する間は、数字の出力後に1が足され続けます。
そのため、0から9の数字を順番に出力することができます。

数字が10になると条件は成立しないので、Noの矢印に進み処理を終了します。

Rubyでは、繰り返し処理を効率的に行える制御構造がいくつか用意されています。その中でも代表的なwhileについて学んでいきます。

ぴかわかさん

whileの基本的な使い方を学ぼう

whileを使うと、条件が成り立つ間は一定の処理を繰り返すことができます。

フローチャート6

それでは実際にサンプルコードを使いながらwhileの基本的な使い方を学び、繰り返しについて理解を深めていきましょう。

whileの基本構文

whileの基本的な書き方は、以下の通りです。

whileの基本構文
1
2
3
while 条件式 do
  # 条件式が真である間に繰り返したい処理
end

条件式には「比較演算子」などを使って、いつまで繰り返すかの条件を指定し、do~end内には、条件が成立するまでの間に繰り返したい処理を指定します。

ifの章では「真偽値」について学びましたが、whileでは条件式が評価されて「真」であれば処理が繰り返し実行されます。

真偽値を復習したい方は、「条件式の評価」を参考にしてください。

ぴかわかさん

whileを使ってみよう

実際にwhileを使って処理を繰り返してみましょう。

ここからは、Rubyのファイルを使います。
while.rbという名前のファイルを「pikawakaフォルダ」の直下に作成しましょう。

前述の具体例で挙げたフローチャートの処理手順をソースコードにします。

フローチャート3

数字にはcountという変数を使います。
上のフローチャートのソースコードは、以下の通りです。

以下のソースコードをwhile.rbに書き、rubyコマンドで実行してみましょう。

while.rb
1
2
3
4
5
6
count = 0

while count <= 9 do
  p count
  count += 1
end

実行すると、動画のように0から9まで順番に数字が出力されます。

while.rbを実行する

このプログラムがどのように出力されているのかを確認してみます。

whileの使い方を確認してみよう

先ほど実行したwhile.rbの内容でwhileの使い方を確認してみます。
フローチャートを使いながら、コメントアウトに記載する1~3の順番で説明します。

while.rb
1
2
3
4
5
6
count = 0 # 1.変数を初期化する

while count <= 9 do # 2.条件を指定する
  p count # 3.繰り返したい処理を記述する
  count += 1 # 変数の値を更新する
end
1.変数を初期化する

まずは、数字を0で初期化します。

初期化

数字には変数countを使います。
初期化とは、宣言した変数に初期値を書き込むことなのでcount0を代入します。

Rubyでは、最初の代入が変数の宣言になります。

while.rb | 変数countを0で初期化する
1
count = 0
2.条件を指定する

次に「数字は9以下か」という条件を指定します。

条件式を指定

「9以下」は9も含まれるので、比較演算子<=を使います。

whileの後に条件式count <= 9を書くことで「countが9以下になるまで繰り返す」という条件が設定できます。

while.rb | いつまで繰り返すかの条件を指定する
1
2
3
count = 0

while count <= 9 do

左辺にcount、右辺に9を置きます。反対にすると違う意味になるので気をつけましょう。

ぴかわかさん
3.繰り返したい処理を書く

最後に条件が成立するまで繰り返したい処理を書きます。

繰り返したい処理を記述

繰り返したい処理は、do~end内に書きます。

pメソッドを使って数字であるcountを出力させます。
次に数字に1を足したいので、自己代入演算子+=countに1を足して代入します。

while.rb | countが9以下の間に繰り返したい処理を書く
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まで順番に出力できます。

処理の流れを確認してみよう

続いて、処理の流れを確認してみます。

繰り返し処理の流れについては、冒頭の「繰り返しの具体例」で少し触れましたが、今回はフローチャートだけではなく、コードと共に説明します。

while.rb
1
2
3
4
5
6
count = 0

while count <= 9 do
  p count
  count += 1
end

処理の流れを把握している方は、次のwhileの注意点に進みましょう。

ぴかわかさん
1回目の処理の流れ

最初にcount0で初期化しているので、途中まで数字は0です。
条件の「数字は9以下か」は成立し、do~end内の処理が上から順番に実行されます。

まずp countによって、0が出力されます。

1回目の処理の流れ1

続いて、以下のようにcountの値が0から1に更新されます。

countの値は0だったので、0 + 11になります。
「2回目の処理の流れ」に入る前に、数字は1に更新されている所がポイントです。

1回目の処理の流れ2

2回目の処理の流れ

「1回目の処理」が終わると、再び条件に戻ります。

この時点での数字は1なので、条件の「数字は9以下か」は成立します。
続いてp countが実行されますが、count1なので1が出力されます。

2回目の処理の流れ1

次の「3回目の処理」に入る前には、以下のように数字が2に更新されます。

2回目の処理の流れ2

このようなdo~end内の処理は「数字が9以下の間」に繰り返し実行されます。

以下のように数字(count)が10になった時点で、「数字が9以下か」という条件は成立しなくなるので、whileの処理を終了します。

whileの処理を終了

whileの注意点(無限ループ)

whileの注意点として、無限ループにならないように注意する必要があります。

無限ループとは、一連の処理が永遠に繰り返されることです。「条件式の結果が変わらないコード」や「条件式を間違える」と無限ループになる恐れがあります。

while.rbでは変数の値を更新させる処理を忘れてしまうと、無限ループになります。

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を使う際には「条件式が偽になるか」など繰り返しが終わる必要があることを念頭におきましょう。

ポイント
  1. whileを使うときは、無限ループにならないように注意しよう
  2. 無限ループとは、一連の処理が永遠と繰り返されてしまうこと
  3. 変数の値を更新させる処理や条件式を間違えると無限ループになる恐れがある

繰り返しの制御

Rubyには、繰り返し処理用の制御構造がいくつか用意されます。

その中でもよく使われる「break」と「next」の使い方を説明します。
breakやnextなどを使うことで、繰り返し処理の動きを変えることができます。

break

breakは、whileなどの繰り返し処理から脱出することができます。

以下のようにwhile.rbbreakを書き、rubyコマンドで実行してみましょう。

while.rb | breakを追加する
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を使う

またbreakのあとに他のコードを記述しても、実行されずにwhileを脱出します。
以下のようにbreakのあとにp countを書き、rubyコマンドで実行してみましょう。

while.rb
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だけが出力されます。

breakの後の処理は実行されない

ポイント
  1. breakは、繰り返し処理から脱出することができる
  2. breakの後のコードは実行されずに繰り返し処理を脱出する

next

nextは、現在の繰り返し処理を途中で中断し、次の繰り返しに移動することができます。

以下のハイライト箇所をwhile.rbに書き、rubyコマンドで実行してみましょう。

while.rb
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を使う例

このようにnextifと使うことで、特定の条件の時に現在の繰り返し処理を中断し、次の繰り返しに移動することができます。

ポイント

nextは、現在の繰り返し処理を途中で中断し、次の繰り返しに移動できる

ブロック付きメソッド(イテレータ)

繰り返しの制御構造ではありませんが、ブロックを活用するメソッド(ブロック付きメソッド)では繰り返し処理を簡潔に書くことができます。

その中でも代表的な「timesメソッド」と「eachメソッド」を簡単に説明します。

timesメソッド

timesメソッドは、指定した回数だけdo~end内の処理を繰り返します。

timesメソッドの基本構文
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 - 13 - 12です。
つまり上記の処理を実行すると、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で、値は男です

繰り返しの制御構造

Rubyの繰り返しの制御構造には、whileだけではなくuntilforがあります。

untilforの使い方については、以下の表のリンク先を参考にしてみてください。

条件分岐 説明 リンク
while 条件式の結果が真のとき繰り返される
until 条件式の結果が偽のとき繰り返される untilの使い方
for オブジェクトの要素分繰り返される forの使い方

この記事のまとめ

  • 繰り返しとは、プログラムの中である条件が成り立つか、もしくは成り立たないかによって、特定の箇所を繰り返し実行させること
  • プログラムの中で特定の箇所を何度も繰り返すことを「ループ」とも呼ぶ
  • 一連の処理が永遠に繰り返される「無限ループ」に注意しよう!