PHPからRailsに移行した人が戸惑うRubyの繰り返し処理の書き方

Ruby on Rails

Rubyにはいろいろな繰り返し処理の書き方があって、PHPや他の言語から入った人は少し戸惑うんじゃないでしょうか(自分がそうでした)

そんな方のためにRubyの繰り返し処理の書き方をまとめてみました

やること

配列に入ってる1から5の数字を順番に出力する機能を例に見てみましょう

list = [1, 2, 3, 4, 5]

1
2
3
4
5

以下のコードはいずれも同じ1から5の番号を順番に出力するメソッドです

繰り返し処理の書き方

PHP

まずは比較のために、PHPで配列を出力する書き方をみてみましょう

PHPで配列の値を一つずつ取り出す場合に、最もよく使うのはforeachでしょう

$list = [1, 2, 3, 4, 5];
 
foreach( $list as $no ){
  echo $no;
}
出力

1
2
3
4
5

Ruby

for

RubyではPHPのforeachはありません

似た関数のforで書くとこのようになります

(が、Rubyではforは推奨されてないので、実際の現場ではこのようなコードは書きません)

list = [1, 2, 3, 4, 5]
 
for no in list
  p no
end
出力

1
2
3
4
5

each

rubyでは、多くのケースでeachを使います

list = [1, 2, 3, 4, 5]
 
list.each do |no|
  p no
end
出力

1
2
3
4
5

do 〜 endの部分を波括弧{}で置き換えることもできます

list = [1, 2, 3, 4, 5]
 
list.each { |no|
  p no
}
出力

1
2
3
4
5

実際の現場では、1行で済むようなケースはこんな感じに改行しないことが多いです

list = [1, 2, 3, 4, 5]
 
list.each { |no| p no }
出力

1
2
3
4
5

map

そしてPHPerにはあまり馴染みがないのがMapです

Mapはブロック内で評価した値(結果)を配列として返却してくれます

list = [1, 2, 3, 4, 5]
 
result = list.map do |no|
  p no
end
 
p result
出力

1
2
3
4
5
[1, 2, 3, 4, 5]

(このような例ではあまりmapを使う意味がありませんが、ブロック内で数値を加算したりする場合に便利なメソッドです)

eachとmapの違い

実はeachもmapも配列を返却してくれますが、それぞれの値は少し異なります

each

list = [1, 2, 3, 4, 5]
 
result = list.each do |no|
  p no+1
end
 
p result
出力

2
3
4
5
6
[1, 2, 3, 4, 5]

上記は、ブロック内で配列の値それぞれに+1を行った結果と、eachから返却された配列を出力したものです

eachブロック内では+1された値が出力されてるのに対して、配列の返却値resultでは値が初期値から変化しません

([1,2,3,4,5]のまま)

map

list = [1, 2, 3, 4, 5]
 
result = list.map do |no|
  p no+1
end
 
p result
出力

2
3
4
5
6
[2, 3, 4, 5, 6]

今度はeachmapに置き換えただけの処理です

返却値resultがブロック内でそれぞれ+1された値になっています

このようにeachの返却値は元々の配列の値なのに対して、mapはブロック内で評価された配列になる、という違いがあります