繰り返し処理の種類
for~要素を取り出して処理する
Rangeオブジェクトを使った繰り返し処理。".."演算子は両端の値を含む。
|
|
for n in 0..5 do print(n, " ") end puts # 0 1 2 3 4 5 |
"..."演算子は終了値を含まない。
|
|
for n in 0...5 do print(n, " ") end puts # 0 1 2 3 4 |
配列の内容を一つずつ取り出す例。
|
|
for n in ["A", "B", "C", "D"] do print n, " " end puts # A B C D |
times~回数を指定する処理
timesは繰り返し回数を指定して実行。
|
|
5.times do print "はい" end puts # はいはいはいはいはい |
繰り返しのカウンターを指定できる。カウンターはゼロからスタートし、指定回数-1までカウントされる。
|
|
5.times do |n| print n, " " end puts # 0 1 2 3 4 |
upto/downto~カウントアップ/ダウン
uptoは初期値から終了値までを含んでカウントアップ。downtoは逆にカウントダウン。カウンターを省略しても可。
|
|
1.upto(5) do |n| print n, " " end puts # 1 2 3 4 5 5.downto(1) do |n| print n, " " end puts # 5 4 3 2 1 |
step~刻み幅を指定
[初期値].step([終了値], [刻み幅])で実行。
|
|
1.5.step(4.0, 0.5) do |n| print n, " " end puts # 1.5 2.0 2.5 3.0 3.5 4.0 1.0.step(-1.0, -0.5) do |n| print n, " " end puts # 1.0 0.5 0.0 -0.5 -1.0 |
終了値がちょうどでない場合はその手前まで実行される。
|
|
1.5.step(4.0, 0.75) do |n| print n, " " end puts # 1.5 2.25 3.0 3.75 2.0.step(-1.5, -0.75) do |n| print n, " " end puts # 2.0 1.25 0.5 -0.25 -1.0 |
ただし浮動小数点の計算誤差があり得るので、ちょっと気持ち悪い。
each~要素を一つずつ取り出す
eachはforと同じくコレクションの要素を順に取り出す。
|
|
[0, 1, 2, 3].each do |n| puts(n) end # 0 # 1 # 2 # 3 |
hashはキーと値を取り出せる。
|
|
{FL:"Florida", IA:"Iowa", OH:"Ohio"}.each do |key, value| puts "#{key} is abbreviation of #{value}" end # FL is abbreviation of Florida # IA is abbreviation of Iowa # OH is abbreviation of Ohio |
ブロックの省略形{...}がある。
|
|
[0, 1, 2, 3].each { |n| puts(n) } # 0 # 1 # 2 # 3 |
each_with_index~要素番号も取得
each_with_indexはコレクションから要素を取り出しながら、そのインデックスも得られる。Pythonのenumerateと同じ機能。
|
|
["A", "B", "C", "D"].each_with_index do |element, index| puts "#{index} - #{element}" end # 0 - A # 1 - B # 2 - C # 3 - D |
while~条件が真の間繰り返し
whileは条件が真の間ブロックを繰り返す。
|
|
n = 0 while n < 5 do print n, " " n += 1 end puts # 0 1 2 3 4 |
whileをbegin…endブロックの後に置ける。上記の前置の場合は条件によってはブロックは一度も実行されないが、後置の場合は少なくとも1回は実行される。
|
|
n = 0 begin print n, " " n += 1 end while n < 5 puts # 0 1 2 3 4 |
until~条件が真になるまで繰り返し
untilはwhileと逆で条件が偽の間繰り返し、真になったらループ終了。whileと同様、ブロックの前/後どちらに置いてもよい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
n = 0 until n >= 5 do print n, " " n += 1 end puts # 0 1 2 3 4 n = 0 begin print n, " " n += 1 end until n >= 5 puts # 0 1 2 3 4 |
loop~無限ループ
loopは単にブロックを繰り返す。ループの終了判定が必要。
|
|
n = 0 loop do print n, " " n += 1 break if n >= 5 end puts # 0 1 2 3 4 |
繰り返し制御
break~ループを終了
breakは実行中のループブロックを終了する。
|
|
for n in 0...5 do print n, " " break if n == 3 end puts # 0 1 2 3 |
next~残りを飛ばして続ける
nextはそれ以下の実行をせず、ループの次のステップに入る。他言語のcontinueと同じ。
以下の例ではn==2のときだけprintが実行されず、次のn=3の処理に入る。
|
|
for n in 0...5 do next if n == 2 print n, " " end puts # 0 1 3 4 |
redo~同じ条件で再実行
redoは現在のループと同じ条件で再度実行する(ループの次のステップではなく同じステップを再実行)。
|
|
n = 0 ["A", "B", "C", "D"].each do |a| puts "#{n} - #{a}" n += 1 redo if n == 3 end # 0 - A # 1 - B # 2 - C # 3 - C # 4 - D |
この例では、n==2の時に"2 - C"を表示。その後n==3となってredoが実行され、a=="C"のままputsから実行、"3 - C"が表示されている。
次の例はすこしややこしい。
|
|
[0, 1, 2, 3].each do |n| print n n += 1 redo if n == 2 end puts # 01223 |
この例ではeachでn=1とセットされて"1"が表示される。その後n==2となるのでredoが実行され、n==2のままprintが実行されて"2"が表示。その後n==3になるので次のeachに移り、n==2がセットされる。このn("2")を表示した後、n==3となるのでredoは実行されず・・・と続く。