Uniq по атрибуту объекта в Ruby - PullRequest
       69

Uniq по атрибуту объекта в Ruby

112 голосов
/ 21 сентября 2008

Какой самый элегантный способ выделить объекты в массиве, которые являются уникальными по одному или нескольким атрибутам?

Эти объекты хранятся в ActiveRecord, поэтому было бы неплохо использовать методы AR.

Ответы [ 13 ]

1 голос
/ 19 июля 2012

Реализация ActiveSupport:

def uniq_by
  hash, array = {}, []
  each { |i| hash[yield(i)] ||= (array << i) }
  array
end
1 голос
/ 11 марта 2012

Мне нравятся ответы Джмы и Хеда. Но они сохраняют порядок массива? Они могут быть в более поздних версиях ruby, поскольку в спецификацию языка были внесены некоторые требования по сохранению порядка вставки хеша, но вот подобное решение, которое мне нравится использовать, сохраняет порядок в любом случае.

h = Set.new
objs.select{|el| h.add?(el.attr)}
0 голосов
/ 21 сентября 2008

Теперь, если вы можете отсортировать значения атрибутов, это можно сделать:

class A
  attr_accessor :val
  def initialize(v); self.val = v; end
end

objs = [1,2,6,3,7,7,8,2,8].map{|i| A.new(i)}

objs.sort_by{|a| a.val}.inject([]) do |uniqs, a|
  uniqs << a if uniqs.empty? || a.val != uniqs.last.val
  uniqs
end

Это для уникального атрибута с 1 атрибутом, но то же самое можно сделать с лексикографической сортировкой ...

...