144 Stimmen

Uniq nach Objekt-Attribut in Ruby

Wie lassen sich Objekte in einem Array, die in Bezug auf ein oder mehrere Attribute eindeutig sind, am elegantesten heraussuchen?

Diese Objekte sind in ActiveRecord gespeichert, so dass die Verwendung von AR-Methoden auch in Ordnung wäre.

6voto

7mode Punkte 66

Utilisez Array#uniq mit einem Block:

objects.uniq {|obj| obj.attribute}

Oder ein prägnanterer Ansatz:

objects.uniq(&:attribute)

5voto

Head Punkte 4541

Ich finde es gut, dass jmah ein Hash verwendet, um die Einzigartigkeit zu gewährleisten. Hier sind ein paar weitere Möglichkeiten, diese Katze zu häuten:

objs.inject({}) {|h,e| h[e.attr]=e; h}.values

Das ist ein netter Einzeiler, aber ich vermute, dass das hier ein bisschen schneller sein könnte:

h = {}
objs.each {|e| h[e.attr]=e}
h.values

4voto

Igbanam Punkte 5665

Der eleganteste Weg, den ich gefunden habe, ist ein Spin-off mit Array#uniq mit einem Block

enumerable_collection.uniq(&:property)

es liest sich auch besser!

3voto

Drew Olson Punkte 3589

Wenn ich Ihre Frage richtig verstehe, habe ich dieses Problem mit dem quasi-hacky Ansatz des Vergleichs der Marshaled-Objekte angegangen, um festzustellen, ob irgendwelche Attribute variieren. Die Injektion am Ende des folgenden Codes wäre ein Beispiel:

class Foo
  attr_accessor :foo, :bar, :baz

  def initialize(foo,bar,baz)
    @foo = foo
    @bar = bar
    @baz = baz
  end
end

objs = [Foo.new(1,2,3),Foo.new(1,2,3),Foo.new(2,3,4)]

# find objects that are uniq with respect to attributes
objs.inject([]) do |uniqs,obj|
  if uniqs.all? { |e| Marshal.dump(e) != Marshal.dump(obj) }
    uniqs << obj
  end
  uniqs
end

2voto

jmah Punkte 2218

Sie können einen Hash verwenden, der für jeden Schlüssel nur einen Wert enthält:

Hash[*recs.map{|ar| [ar[attr],ar]}.flatten].values

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X