map/collect
mapメソッド(collectはエイリアスメソッド)
mapは各要素に対してブロックを評価した結果を新しい配列にして返すメソッド。
#mapを使わない場合↓
numbers = [1,2,3,4]
new_numbers = []
numbers.each{|n| new_numbers << n * 10 }
puts new_numbers
=> [10,20,30,40]
#mapを使った場合↓
numbers = [1,2,3,4]
new_numbers = numbers.map{ |n| n * 10}
puts new_numbers
=> [10,20,30,40]
空の配列を用意して他の配列をループ処理した結果を空の配列に入れるような処理の多くは、mapメソッドを使って置き換えることができる。
select/find_all/reject
selectメソッド(find_allはエイリアスメソッド)
各要素に対してブロックを評価し、その戻り値が真の要素を集めた配列を返すメソッド。
#selectメソッド
#配列から偶数だけを集めた配列を作る場合
numbers = [1,2,3,4,5,6]
even_numbers = numbers.select{|n| n.even?}
even_numbers
=>[2,4,6]
rejectメソッドはselectメソッドの反対で、ブロックの戻り値が真になった要素を除外します。言い換えると戻り値が偽である要素を集めるメソッドです。
#rejectメソッド
#2で割り切れる数字はrejectで省かれる。つまり2で割り切れない数字だけの配列ができる。
numbers = [1,2,3,4,5,6]
non_multiples_of_two = numbers.reject{ |n| n % 2 == 0}
non_multiples_of_two
=>[1,3,5]
find/detect
findメソッド(detectはエイリアスメソッド)はブロックの戻り値が真になった最初の要素を返します。
numbers = [1,2,3,4,5,6]
even_number = numbers.find{ |n| n.even?}
even_number
=> 2
inject/reduce
injectメソッド(エイリアスメソッドはreduce)
numbers = [1,2,3,4]
sum = numbers.inject(0){ |result,n| result + n}
sum
=> 10
- 1回目:result=0,n=1で、0+1=1。これが次のresultに入る。
- 2回目:result=1,n=2で、1+2=3。これが次のresultに入る。
- 3回目:result=3,n=3で、3+3=6。これが次のresultに入る。
- 4回目:result=6,n=4で、6+4=10。最後の要素に達したのでこれがinjectの戻り値になる。
&とシンボルを使ってもっと簡潔に書く
['apple','banana','mango'].map {|n| n.upcase}
=>["APPLE", "BANANA", "MANGO"]
#こう書くこともできる。
['apple','banana','mango'].map(&:upcase)
=>["APPLE", "BANANA", "MANGO"]
下記の条件が揃ったときにはこの書き方が使える。
- ブロック引数が一つだけ
- ブロックの中で呼び出すメソッドには引数が無い。
- ブロックの中では、ブロック引数に対してメソッドを一回呼び出す以外の処理がない。