繰り返し処理(ループ)とは
- 繰り返し処理とは、決まった回数や条件を満たしているは同じ処理を繰り返し行う場合に使います。
- Rubyの繰り返し処理は配列やハッシュのメソッドなどの、制御構造内での繰り返し処理や、ブロック付きメソッド呼び出しという制御構造を定義する事ができるものまで多くの種類があります。
- 今回はその中でよく使う4つを簡略的に紹介します。
eachメソッド
eachメソッドはRubyにおいて非常にメジャーな繰り返し処理の1つであり、配列やハッシュなどのコレクションオブジェクトを操作する際によく使われます。
-
eachメソッド 構文ここでのcollection.each do |変数| # 処理 endcollectionは繰り返し処理を行う対象となるオブジェクトで、変数はブロック内のdo ~ endで各要素を受け取るための変数名です。- 配列を対象とした
eachの例このコードではfruits = ["apple", "banana", "orange"] fruits.each do |fruit| puts fruit endfruits配列の各要素をfruitという変数に代入して、putsメソッドで出力しています。出力apple banana orange
- 配列を対象とした
each_with_indexメソッド
-
eachメソッドの派生でeach_with_indexメソッドというのがあります。
eachメソッドと同様に繰り返しの処理を行いつつ、各要素のインデックスも同時に受け取ることができます。each_with_indexcollection.each_with_index do |item, index| # ブロックでの処理 endcollectionに繰り返し処理を行いたい配列やハッシュなどを指定し、ブロック内でのitemには配列の要素やハッシュの値、indexには配列のインデックスやハッシュのキーが渡されます。このコードを実行すると以下の様に出力されるが、インデックス番号は0から始まっている。each_with_indexfruits = ['apple', 'banana', 'orange'] fruits.each_with_index do |fruit, i| puts "#{i}: #{fruit}" endこの番号を出力0: apple 1: banana 2: orangeeach_with_indexメソッドの第2引数に、インデックス番号の開始値を指定することで番号を任意の位置から始める事ができます。each_with_index(1)fruits = ['apple', 'banana', 'orange'] fruits.each_with_index(1) do |fruit, index| puts "#{index}: #{fruit}" end #出力結果 #=> 1: apple #=> 2: banana #=> 3: orange
timesメソッド
timesメソッドは整数オブジェクトに対して利用でき、指定した回数だけ繰り返し処理を実行するメソッドです。
-
timesメソッド 構文times構文回数.times do |変数| # 繰り返したい処理 end #または 回数.times { |変数| # 繰り返したい処理 }回数には繰り返し回数を指定し、ブロック内の処理が指定した回数文繰り返されます。ブロック内には繰り返し処理で使用するための変数を定義する事ができます。
変数の部分は省略可能で、以下の様に簡略化して書くこともできます。3.times do puts "Hello, world!" end #=> Hello, world! #=> Hello, world! #=> Hello, world!ただし、
timesメソッドのブロック変数には繰り返し処理が現在何回目であるかを示す数値が自動的に格納されます。3.times do |i| puts "Hello, world! #{i + 1}" end #=> Hello, world! 1 #=> Hello, world! 2 #=> Hello, world! 3puts文内でi + 1とすることで、出力されるテキストの末尾に現在の繰り返し回数を追加しています。
mapメソッド
mapメソッドは配列や範囲オブジェクトの要素を変換するために使用されるメソッドです。元の配列を変更するのではなく、変換された新しい配列を返します。
また、mapメソッドは要素ごとにブロックを実行し、ブロックの戻り値を配列に格納します。
-
mapメソッド 構文map 構文array.map { |item| block }上記の
arrayは変換したい配列を指定しています。
itemは配列の各要素がブロックに渡される際の引数で、blockは配列の各要素に対して実行されるブロックです。
mapメソッドはブロックの戻り値を新しい配列の要素として格納してその配列を返します。mapメソッドの例arr = [1, 2, 3, 4, 5] new_arr = arr.map { |n| n * 2 } puts new_arr # => [2, 4, 6, 8, 10]上記の例では
arrという配列の各要素に対して2倍した新しい配列を作成している。mapメソッド内のn * 2によって各要素を2倍して、新しい配列であるnew_arrに代入している。mapメソッドは他のメソッドと組み合わせて使用することができて便利です。
後述するselectメソッドとの併用もでき、mapメソッドで配列の要素を変更した新しい配列を作成したあと、selectメソッドを使って条件に一致する要素だけを抽出する事もできます。-
mapとselectを組み合わせて、配列から条件に合う要素だけを抜き出す。numbers = [1, 2, 3, 4, 5, 6] even_numbers = numbers.select { |n| n.even? } # => [2, 4, 6] squared_even_numbers = even_numbers.map { |n| n**2 } # => [4, 16, 36] -
mapとreduceを組み合わせて、配列の各要素を処理し、その結果を合算する。numbers = [1, 2, 3, 4, 5] sum_of_squares = numbers.map { |n| n**2 }.reduce(0) { |sum, n| sum+ n } # => 55 -
mapとwith_indexを組み合わせて、配列の各要素に対して、そのインデックス番号も一緒に扱う。fruits = ["apple", "banana", "orange"] fruits_with_index = fruits.map.with_index { |f, i| "#{i}: #{f}" } # => ["0: apple", "1: banana", "2: orange"]
-
while文
while文は、指定された条件式がtrueの時に繰り返し処理を行う制御構造です。条件式がfalseになると、while文を抜けて次の処理に進みます。条件式が一度もfalseにならずに永遠にループすることもあります。
-
while文 構文while 構文while 条件式 do # 繰り返したい処理 endwhile文は条件を満たしている限り何度も同じ処理を繰り返すので、データの処理をすべてのデータが処理されるまで繰り返したい場合などに使えます。上記の例では、変数i = 1 while i <= 10 do puts i i += 1 endiが1から10になるまで繰り返し処理を行っています。
iが10になると条件式のi <= 10がfalseとなるので、while文を抜けて次の処理に進みます。出力1 2 3 4 5 6 7 8 9 10 -
while文ではループを行う際に、条件式が常にtrueにならないようにループ内で条件式が変更されるようにする必要があります。
そうでないと、無限ループに陥り条件を抜け出せなくなる可能性があります。 -
while文の条件式は、比較演算子などを用いて真偽値を返すようにします。 - 以上の点を踏まえて
while文を使用する際は条件式がどのようなときにループを終了するか、あらかじめ明確に決めておく必要があります。
まとめ
この記事では、繰り返し処理を行う場面でよく使うものを紹介しました。
Rubyでは基本的にeachを使うのがメジャーらしいので、仕組みを理解してマスターしていこうと思いました。
mapメソッドについては繰り返し処理とは違った内容になってしまいましたが、よく使う繰り返し処理と合わせて便利なメソッドなのでそのまま勢いで載せてしまいました。
次は繰り返し処理を行う上で必要なbreakの概要と使い方と使用例、注意事項などをまとめてみたいと思います。
はじめての投稿で拙いところもあると思いますが、自分と同じくRuby初学者の為になれば幸いです。