Uniq by object attribute in Ruby

前端 未结 14 1891
我寻月下人不归
我寻月下人不归 2020-11-30 23:20

What\'s the most elegant way to select out objects in an array that are unique with respect to one or more attributes?

These objects are stored in ActiveRecord so us

14条回答
  •  情话喂你
    2020-11-30 23:59

    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
    

提交回复
热议问题