はじめに
今回はfilter_mapに関する内容です。Ruby3.1の新しい概念の一つにfilter_mapメソッドがあるので簡単にまとめてみます。
確認してみた
環境はruby 3.1.4です。
こちらによると、filter_mapメソッドは各要素に対してブロックを評価した値のうち、真であった値のみの配列を返すメソッドらしいです。
実際に配列に対してfilter_mapメソッドを実行
fruits = ["banana", "pineapple", "grape", "apple", "grape", "pineapple", false, nil]
fruits.filter_map{|fruit| fruit}
すると、
irb(main):001> fruits = ["banana", "pineapple", "grape", "apple", "grape", "pineapple", false, nil]
irb(main):002> fruits.filter_map{|fruit| fruit}
=> ["banana", "pineapple", "grape", "apple", "grape", "pineapple"]
falseとnilが除外された配列が返ってくる。
filter_mapメソッドを使用しないパターンで同じ結果を返す方法をchatgptに聞いてみると、
fruits = ["banana", "pineapple", "grape", "apple", "grape", "pineapple", false, nil]
# filter_mapの代わりにselectとmapを使用
result = fruits.select { |fruit| fruit }.map { |fruit| fruit }
が返ってきて、実際に試すと、
irb(main):001> fruits = ["banana", "pineapple", "grape", "apple", "grape", "pineapple", false, nil]
=> ["banana", "pineapple", "grape", "apple", "grape", "pineapple", false, nil]
irb(main):002>
irb(main):003> # filter_mapの代わりにselectとmapを使用
irb(main):004> result = fruits.select { |fruit| fruit }.map { |fruit| fruit }
=> ["banana", "pineapple", "grape", "apple", "grape", "pineapple"]
filter_mapメソッドを使用した結果と同じ結果となりました。
おわりに
確認した結果、filter_mapメソッドは各要素に対してブロックを評価した値のうち、真であった値のみの配列を返すことが分かりました。また、filter_map以外の方法でfilter_mapメソッドと同じ結果を出す方法も確認した結果、selectとmapを使う方法がありました。selectとmapを使う方法の場合、ブロック操作が2回でてくるため、filter_mapを使用した方がよりシンプルになる気がしました。(今回の配列からfalseとnilを除外してそのまま返すコードではselectのみで実装できますが、動きとしてはselectとmapの組み合わせが正しいようです)。実際、配列の中に偽の値が入ってきてうまく処理できずにシステムエラーになる場面も割とあるのかと思うので、filter_mapメソッドを活用していこうと思います。もし誤っていたらご指摘いただけると助かります!
参考