for文はコレクション(配列や範囲)の各要素に対して順番に処理を行う繰り返し構文です。Rubyではeachメソッドの方がよく使われますが、for文は他の言語から来た方にも馴染みやすい構文です。この記事ではfor文の基本から、eachとの違いまで解説します。
基本的な使い方
範囲(Range)を使ったfor文
for文はfor 変数 in コレクションの形式で記述します。
Ruby
for i in 1..5
puts "#{i}回目の繰り返し"
end実行結果
1回目の繰り返し
2回目の繰り返し
3回目の繰り返し
4回目の繰り返し
5回目の繰り返し1..5は1から5までの範囲オブジェクトで、for文は各要素を順番に変数iに代入して処理を実行します。1...5(ドット3つ)にすると末尾を含まない1から4までの範囲になります。
配列を使ったfor文
Ruby
fruits = ['りんご', 'バナナ', 'みかん', 'ぶどう']
for fruit in fruits
puts "果物: #{fruit}"
end実行結果
果物: りんご
果物: バナナ
果物: みかん
果物: ぶどうfor文とeachの違い
for文とeachメソッドの最大の違いは変数のスコープです。
Ruby
# for文: ループ変数がブロック外でもアクセス可能
for i in 1..3
x = i
end
puts "for文後のx: #{x}" # アクセスできる
# each: ブロック変数はブロック外からアクセスできない
(1..3).each do |j|
y = j
end
puts "each後のy: #{y}" # yにはアクセスできる(ブロック外で定義されたため)
# puts j # エラー!jはブロック内でのみ有効実行結果
for文後のx: 3
each後のy: 3for文のループ変数iはfor文の外でも有効です。一方、eachのブロック変数|j|はブロック内でのみ有効です。変数のスコープを限定できるeachの方がバグを防ぎやすいため、Rubyではeachが推奨されています。
実践的な使い方
九九の表
Ruby
for i in 1..5
row = ''
for j in 1..5
row += "#{(i * j).to_s.rjust(3)}"
end
puts row
end実行結果
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25合計と平均の計算
Ruby
scores = [85, 92, 78, 95, 67, 88]
total = 0
max = scores[0]
min = scores[0]
for score in scores
total += score
max = score if score > max
min = score if score < min
end
puts "成績: #{scores.inspect}"
puts "合計: #{total}"
puts "平均: #{(total.to_f / scores.length).round(1)}"
puts "最高点: #{max}"
puts "最低点: #{min}"実行結果
成績: [85, 92, 78, 95, 67, 88]
合計: 505
平均: 84.2
最高点: 95
最低点: 67ハッシュの配列を処理
Ruby
students = [
{name: '田中', score: 85},
{name: '佐藤', score: 92},
{name: '鈴木', score: 78}
]
for student in students
grade = student[:score] >= 80 ? '合格' : '再試'
puts "#{student[:name]}: #{student[:score]}点(#{grade})"
end実行結果
田中: 85点(合格)
佐藤: 92点(合格)
鈴木: 78点(再試)Rubyではeachが主流
Rubyコミュニティではfor文よりもeachメソッドが広く使われています。eachはブロック変数のスコープが限定されるため安全で、Rubyらしいイディオムです。for文は他の言語に慣れた方への橋渡しとして知っておくと便利です。
for文のスコープに注意
for文のループ変数はfor文の外でも参照できてしまいます。意図せず同名の変数を上書きするバグが起こりやすいため、特にこだわりがなければeachを使いましょう。
まとめ
for 変数 in コレクションで繰り返し処理を行う- 範囲(Range)や配列を対象にできる
- for文のループ変数はブロック外でも有効(スコープが広い)
- Rubyでは
eachメソッドの方が推奨されている - ネストしたfor文で二次元的な処理も可能