🍒

【Ruby】組み込みクラスの類似メソッド達

2022/05/07に公開

find_all / select

ブロック内の式が真になる要素を全て含む配列を返す。

各要素に対してブロックを評価した値が真であった要素を全て含む配列を返します。
真になる要素がひとつもなかった場合は空の配列を返します。
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/filter.html

# 2で割り切れるものを返す(select)
[1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 }
=> [2, 4, 6]

# 2で割り切れるものを返す(find_all)
[1, 2, 3, 4, 5, 6].find_all { |n| n % 2 == 0 }
=> [2, 4, 6]

# 2で割り切れるものがないので空の配列を返す
[1, 3, 5, 7].select { |n| n % 2 == 0 }
=> []

reject

ブロック内の式が偽になる要素を全て含む配列を返す。
selectの反対です。

各要素に対してブロックを評価し、その値が偽であった要素を集めた新しい配列を返します。条件を反転させた select です。
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/reject.html

# 2で割り切れない要素を返す
[1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 }
=> [1, 3, 5]

find / detect

ブロック内の式が真になった最初の要素を返す。

要素に対してブロックを評価した値が真になった最初の要素を返します。
真になる要素が見つからず、ifnone も指定されていないときは nil を返します。
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/detect.html

# 最初の3の倍数を返す(find )
[1, 2, 3, 4, 5, 6].find { |n| n % 3 == 0 }
=> 3

# 最初の3の倍数を返す(detect)
[1, 2, 3, 4, 5, 6].detect { |n| n % 3 == 0 }
=> 3

# 2で割り切れるものがないので、nilを返す
[3, 3, 3, 3, 3].find { |n| n % 2 == 0 }
=> nil

map / collect

配列の要素の数だけブロック内で処理を繰り返して、新しい配列を返す。

各要素に対してブロックを評価した結果を全て含む配列を返します。
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/collect.html

# 配列内の要素を2倍にした新しい配列を返す(map)
[1, 2, 3, 4, 5, 6].map { |n| n * 2 }
=> [2, 4, 6, 8, 10, 12]

# 配列内の要素を2倍にした新しい配列を返す(collect)
[1, 2, 3, 4, 5, 6].collect { |n| n * 2 }
=> [2, 4, 6, 8, 10, 12]

mapとeachとの違い

eachは、配列内の要素を一つずつ取り出します。

各要素に対してブロックを評価します。
https://docs.ruby-lang.org/ja/latest/method/Array/i/each.html

map → 処理結果を新しい配列として返す
each → 配列内の要素を取り出す

mapは、新しい配列を返すのでレシーバの値も変わる
eachは、戻り値が元の配列のまま

# (map)配列内の要素を2倍にした新しい配列を返す
a = [1, 2, 3, 4, 5, 6].map { |n| p n * 2 }
=> [2, 4, 6, 8, 10, 12]

# 返り値はmapの処理の新しい配列
p a
=> [2, 4, 6, 8, 10, 12]

# (each)配列内の要素を2倍にした結果を返す
b = [1, 2, 3, 4, 5, 6].each { |n| n * 2 }
2
4
6
8
10
12

# 返り値は元の配列のまま
p b
=> [1, 2, 3, 4, 5, 6]

delete_if / reject!

ブロック内の式が偽になる要素を全て含む配列を返す。

要素を順番にブロックに渡して評価し、その結果が真になった要素をすべて削除します。
delete_if は常に self を返しますが、reject! は要素が 1 つ以上削除されれば self を、 1 つも削除されなければ nil を返します。
https://docs.ruby-lang.org/ja/latest/method/Array/i/delete_if.html

# 2で割り切れない(偽になる要素)結果を返す(delete_if)
a = [1, 2, 3, 4, 5, 6].delete_if { |n| n % 2 == 0 }
=> [1, 3, 5]

# 2で割り切れない(偽になる要素)結果を返す(reject!)
a = [1, 2, 3, 4, 5, 6].reject! { |n| n % 2 == 0 }
=> [1, 3, 5]

# 破壊的なメソッドなので、レシーバの値も変わる
p a
=> [1, 3, 5]

補足  Enumerableモジュール

find_all,detect,reject,mapなどはEnumerableモジュールのメソッドです。

配列やハッシュに抽出や検索の機能を与えることができるモジュール
Array, Hash, Range等のクラスで、 Enumerableモジュールはインクルードされている
https://docs.ruby-lang.org/ja/latest/class/Enumerable.html

Discussion