Ruby の繰り返し処理:each・times・map の使い分け

スポンサーリンク

Ruby の繰り返し処理:each・times・map の使い分け

Ruby の繰り返し処理は eachtimesmap などのメソッドで書きます。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 は元の配列を変えず新しい配列を返します。collectmap の別名です。

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 の使い方」を参照してください。