Uniq by object attribute in Ruby
Add the uniq_by
method to Array in your project. It works by analogy with sort_by
. So uniq_by
is to uniq
as sort_by
is to sort
. Usage:
uniq_array = my_array.uniq_by {|obj| obj.id}
The implementation:
class Array def uniq_by(&blk) transforms = [] self.select do |el| should_keep = !transforms.include?(t=blk[el]) transforms << t should_keep end endend
Note that it returns a new array rather than modifying your current one in place. We haven't written a uniq_by!
method but it should be easy enough if you wanted to.
EDIT: Tribalvibes points out that that implementation is O(n^2). Better would be something like (untested)...
class Array def uniq_by(&blk) transforms = {} select do |el| t = blk[el] should_keep = !transforms[t] transforms[t] = true should_keep end endend
Do it on the database level:
YourModel.find(:all, :group => "status")