繰り返し処理(ループ)とは
- 繰り返し処理とは、決まった回数や条件を満たしているは同じ処理を繰り返し行う場合に使います。
- Rubyの繰り返し処理は配列やハッシュのメソッドなどの、制御構造内での繰り返し処理や、ブロック付きメソッド呼び出しという制御構造を定義する事ができるものまで多くの種類があります。
- 今回はその中でよく使う4つを簡略的に紹介します。
each
メソッド
each
メソッドはRubyにおいて非常にメジャーな繰り返し処理の1つであり、配列やハッシュなどのコレクションオブジェクトを操作する際によく使われます。
-
each
メソッド 構文ここでのcollection.each do |変数| # 処理 end
collection
は繰り返し処理を行う対象となるオブジェクトで、変数
はブロック内のdo ~ end
で各要素を受け取るための変数名です。- 配列を対象とした
each
の例このコードではfruits = ["apple", "banana", "orange"] fruits.each do |fruit| puts fruit end
fruits
配列の各要素をfruit
という変数に代入して、puts
メソッドで出力しています。出力apple banana orange
- 配列を対象とした
each_with_index
メソッド
-
each
メソッドの派生でeach_with_index
メソッドというのがあります。
each
メソッドと同様に繰り返しの処理を行いつつ、各要素のインデックスも同時に受け取ることができます。each_with_indexcollection.each_with_index do |item, index| # ブロックでの処理 end
collection
に繰り返し処理を行いたい配列やハッシュなどを指定し、ブロック内でのitem
には配列の要素やハッシュの値、index
には配列のインデックスやハッシュのキーが渡されます。each_with_indexfruits = ['apple', 'banana', 'orange'] fruits.each_with_index do |fruit, i| puts "#{i}: #{fruit}" end
出力0: apple 1: banana 2: orange
each_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! 3
puts
文内で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 # 繰り返したい処理 end
while
文は条件を満たしている限り何度も同じ処理を繰り返すので、データの処理をすべてのデータが処理されるまで繰り返したい場合などに使えます。上記の例では、変数i = 1 while i <= 10 do puts i i += 1 end
i
が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初学者の為になれば幸いです。