高木のブログ

【Ruby】2.7 から追加された Enumerable#filter_map メソッドが便利

2022/06/26

業務でも Ruby 3.1 を使うようになって今更感あるけど、2.7 から追加された Enumerable#filter_map が便利だったので紹介

名前からわかるように、Enumerable#filterEnumerable#map を合体させたメソッド
ちなみに Enumerable#filterEnumerable#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 を積極的に使っていきたい

参考


ytkg

Written by ytkg, Twitter, GitHub