Uniq by object attribute in Ruby
Solution 1:
Use Array#uniq
with a block:
@photos = @photos.uniq { |p| p.album_id }
Solution 2:
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
end
end
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
end
end
Solution 3:
Do it on the database level:
YourModel.find(:all, :group => "status")