Rubyのfilter(select)とfind(detect)の違い

Ruby

filter(select)について

filterは条件を満たす全ての要素を取り出すメソッドです。selectfilterのエイリアス(等価のメソッド)です。filterの例は以下の通りです。

> [1, 2, 3, 4, 5, 6].filter {|i| i % 3 == 0 }
=> [3, 6]

参考: rejectを利用するとselectの逆の結果が得られる

rejectはブロックの評価が偽の要素を集めた配列を返すため、selectの逆の結果が得られます。

> [1, 2, 3, 4, 5, 6].reject {|i| i % 3 == 0 }
=> [1, 2, 4, 5]

find(detect)について

findは条件を満たした最初の要素を返すメソッドです。detectfindのエイリアス(等価のメソッド)です。findの例は以下の通りです。findの例は以下の通りです。

> [1, 2, 3, 4, 5, 6].find {|i| i % 3 == 0 }
=> 3

filterとfindの使いわけ

filterは条件を満たす要素全てを返します。ですのでfilterは条件を満たす要素が複数存在するケースで利用します。
以下はfilterを利用してis_activetrueなUserを取得する例です。

users = []
3.times do  |i|
  users << User.new(id: "#{i + 1}", name: "user_#{i + 1}", is_active: "#{i.even?}")
end

> users.filter { |user| user.is_active? }
=> [#<User:0x0000562b91e44518 id: 1, name: "user_1", is_active: true, created_at: nil, updated_at: nil>,
 #<User:0x0000562b91e27530 id: 3, name: "user_3", is_active: true, created_at: nil, updated_at: nil>]

一方、findは条件を満たした要素のうち最初の1要素のみを返します。ですのでfindは主キーのように要素が一意に定まる条件で検索をするケースで利用します。
以下はfindを利用してidが1のUserを取得する例です。

users = []
3.times do  |i|
  users << User.new(id: "#{i + 1}", name: "user_#{i + 1}", is_active: "#{i.even?}")
end

> users.find { |user| user.id == 1 }
=> #<User:0x0000562b91e44518 id: 1, name: "user_1", is_active: true, created_at: nil, updated_at: nil>

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考資料