繰り返し

ここでは、Rubyの繰り返し処理について説明します。

繰り返し処理とは、なんらかの処理を繰り返すことです。

これについては、例を見た方が分かりやすいでしょう。

for

forを使うことで、繰り返し処理ができます。

for i in 1..10 do
  puts i
end

このソースコードを実行すると、1から10の整数を表示します。

1..10は、1から10の整数を表すオブジェクトです。forの後ろに書いたiという変数に1から10の変数が順に代入されて、do endに記述された処理を実行します。

ここでは、1..10としましたが、配列を指定することで、それらに代入されている値を順に取り出すこともできます。

fruits = ['banana', 'orange', 'apple']
for str in fruits
  puts str
end

今までのソースコードでは、上から順に実行されていたのですが、今回の繰り返し処理から処理が上へ戻るようになりました。そのため,処理の流れを追う際には注意が必要です。

each

配列の中身を使って処理をする場合には、eachを使う方法もあります。

fruits = ['banana', 'orange', 'apple']
fruits.each do |str|
  puts str
end

eachの場合は、変数の後ろに.eachのように書き、do |変数名| 処理 endのように書きます。

基本的に配列を使う場合は、forよりもeachを使う方が多いです。これは、可読性の点で、eachの方が分かりやすいことからeachが使われています。

eachはハッシュでも使用できます。

dic = { banana: 'バナナ', orange: 'オレンジ', apple: 'りんご' }
dic.each do |d|
  puts d
end

dic.each do |key, value|
  puts "#{key}:#{value}"
end

ハッシュの場合は、変数の数をひとつとした場合は、キーとバリューが一緒に変数へ代入されます。変数の数をふたつとした場合は、ひとつめにキーがふたつめにバリューが渡されます。

whileとuntil

条件に当てはまる間だけ、処理を繰り返し実行するものにwhileとuntilがあります。

i = 1
while i <= 10 do
  puts i
  i += 1
end

i = 1
until i > 10 do
  puts i
  i += 1
end

whileやuntilの後に条件式を記述します。whileでは、条件式が真の間、untilでは、条件式が偽の間処理を実行します。

実行する処理はdo endの中に記述します。

無限ループ

Rubyでは、無限ループを実現する専用のものがあります。

counter = 0
loop do
  puts '無限ループ'

  counter += 1
  if counter >= 1000 do
    break
  end
end

loopと記述した後にdo endと記述し、その中に実行する処理を記述します。これは無限ループを実現するための方法のため、何もしなければ、絶対に終了することはありません。

もし、無限ループを抜けるのであれば breakというものを使用します。

ここでは、ifを使用してifの条件式が真の時に無限ループを抜けます。

map

Rubyの便利な処理のひとつにmapがあります。mapは、配列やハッシュなどに格納されているそれぞれの値を変更するためのものです。

fruits = ['banana', 'orange', 'apple']
hot_fruits = fruits.map { |str|
  'hot ' + str
}

p hot_fruits

fruits.map! { |str|
  'hot ' + str
}

p fruits

mapの使い方は、eachと似ています。mapの後ろに{ |変数名| }を記述して、その中に処理を記述します。

この処理の戻り値で、それぞれの値が変更されます。戻り値については、メソッドの説明の際にで詳しく説明するので、ここでは、そんなものがあるんだという程度に思っていてください。

mapは、値の変更の際に新しくオブジェクトを作成します。そのため、別の変数を用意してそれに代入します。もし、もとのオブジェクトに代入する場合は、map!のように!をつけます。

do endと{ }

今回、処理を記述する際にdo endまたは{ }の中に処理を記述しました。これらは、優先順位がことなるだけで、やっていることは同じです。優先順位としては、{ }の方がdo endよりも上です。

しかし、どちらも同じことができるのであれば、どっちを使ってもいいと思うかもしれませんが、Rubyにおいては暗黙の了解があります。

暗黙の了解として、{ }は戻り値を受け取る処理に使用し、do endは戻り値を受け取らない処理で使用します。

今回のサンプルでもこれを意識して使用しているため、foreachwhileuntilでは、do endを、mapでは{ }を使用しています。

まとめ

繰り返し処理を使うことで、データを効率的に扱うことができます。また、ソースコードを短くわかりやすく書くことができるようになります。

なるべく繰り返し処理を使うことができる場所では、使うようにすることでプログラミングが楽になりますので、積極的に使っていきましょう。