Ruby の繰り返し処理:each・times・map の使い分け
Ruby の繰り返し処理は each・times・map などのメソッドで書きます。for 文より簡潔で Ruby らしい書き方になります。
早わかりまとめ
| メソッド | 向いている用途 |
|---|---|
each |
配列・ハッシュの全要素を処理する |
times |
n 回繰り返す |
upto / downto |
数値の範囲を順に処理する |
map / collect |
変換した新しい配列を作る |
each_with_index |
インデックスも使いながら繰り返す |
each_with_object |
結果をオブジェクトに積み上げる |
each:配列の全要素を処理する
names = ['Alice', 'Bob', 'Carol'] names.each do |name| puts name end # Alice # Bob # Carol
ブロックが1行なら波括弧で書けます。
names.each { |name| puts name }
times:n 回繰り返す
3.times do puts 'hello' end # hello # hello # hello # カウンターが必要な場合 5.times do |i| puts i end # 0 # 1 # 2 # 3 # 4
upto / downto:数値の範囲を順に処理する
# 1 から 5 まで 1.upto(5) { |i| print "#{i} " } # 1 2 3 4 5 # 5 から 1 まで 5.downto(1) { |i| print "#{i} " } # 5 4 3 2 1
範囲オブジェクトを使う書き方もよく使います。
(1..5).each { |i| print "#{i} " } # 1 2 3 4 5 (1...5).each { |i| print "#{i} " } # 1 2 3 4(末尾を含まない)
map / collect:変換した新しい配列を作る
prices = [100, 200, 300] # 税込み価格の配列を作る with_tax = prices.map { |price| (price * 1.1).round } p with_tax # [110, 220, 330]
map は元の配列を変えず新しい配列を返します。collect は map の別名です。
users = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }]
names = users.map { |user| user[:name] }
p names # ['Alice', 'Bob']
each_with_index:インデックスを使う
fruits = ['apple', 'banana', 'cherry'] fruits.each_with_index do |fruit, index| puts "#{index}: #{fruit}" end # 0: apple # 1: banana # 2: cherry
each_with_object:結果を積み上げる
words = ['hello', 'world', 'ruby'] # 文字列の長さのハッシュを作る lengths = words.each_with_object({}) do |word, hash| hash[word] = word.length end p lengths # {"hello"=>5, "world"=>5, "ruby"=>4}
for 文との違い
Ruby では for 文よりブロックを使うメソッドが慣例です。for 文はブロックスコープを作らないため、変数がループ外に漏れる点が異なります。
# Ruby らしくない書き方 for name in names puts name end # Ruby らしい書き方 names.each { |name| puts name }
まとめ
| したいこと | 使うもの |
|---|---|
| 配列の全要素を処理する | each |
| n 回繰り返す | times |
| 数値の範囲を処理する | upto / downto / (1..n).each |
| 変換した配列を作る | map |
| インデックスも使う | each_with_index |
| 結果をオブジェクトに積む | each_with_object |
配列の絞り込みは「Ruby 配列の絞り込み:select・reject・find の使い方」を参照してください。