【Ruby】2.7 から追加された Enumerable#filter_map メソッドが便利
2022/06/26
業務でも Ruby 3.1 を使うようになって今更感あるけど、2.7 から追加された Enumerable#filter_map が便利だったので紹介
名前からわかるように、Enumerable#filter と Enumerable#map を合体させたメソッド
ちなみに Enumerable#filter は Enumerable#select のエイリアス
使用例
「1から10まで数字の配列から、偶数のみを2倍にした数字の配列を返す」は以下のように書ける
(1..10).filter_map { |n| n * 2 if n.even? }
=> [4, 8, 12, 16, 20]
今までのやり方
パッと思いつくのは以下の3つ
select + map
(1..10).select(&:even?).map { |n| n * 2 }
=> [4, 8, 12, 16, 20]
map + compact
(1..10).map { |n| n * 2 if n.even? }.compact
=> [4, 8, 12, 16, 20]
each_with_object
(1..10).each_with_object([]) { |n, arr| arr.push(n * 2) if n.even? }
=> [4, 8, 12, 16, 20]
所感
簡潔に書けて良い(賛否両論あるらしいけど、個人的にはこっちの方がわかりやすい)
長さでいうと select + map の方が短いが、2回ループが走るのでパーフォマンスが悪い
内部で select + map をしていたら意味ないけど(後日、内部実装を確認してみる)
いつも each_with_object を使うことが多かったけど、これからは filter_map を積極的に使っていきたい