什么是选择具有一个或多个属性独特对象的最优雅的方法?
这些对象存储在ActiveRecord中,因此使用AR的方法也可以。
什么是选择具有一个或多个属性独特对象的最优雅的方法?
这些对象存储在ActiveRecord中,因此使用AR的方法也可以。
uniq_by
方法到数组中。它类似于sort_by
方法。因此,uniq_by
相当于uniq
,就像sort_by
相当于sort
一样。用法:uniq_array = my_array.uniq_by {|obj| obj.id}
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
uniq_by!
方法,但如果您想要的话,应该很容易实现。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
在数据库层面上进行操作:
YourModel.find(:all, :group => "status")
@photos = @photos.uniq { |p| [p.album_id, p.author_id] }
我最初建议在数组上使用select
方法。如下:
[1, 2, 3, 4, 5, 6, 7].select{|e| e%2 == 0}
返回[2,4,6]
。
但是如果你想要第一个符合条件的对象,请使用detect
。
[1, 2, 3, 4, 5, 6, 7].detect{|e| e>3}
返回4
。
不过我不确定你的意思是什么。
我喜欢jmah使用哈希来实现唯一性。以下是另外几种实现方式:
objs.inject({}) {|h,e| h[e.attr]=e; h}.values
这是一个不错的一行代码,但我怀疑这可能会更快:
h = {}
objs.each {|e| h[e.attr]=e}
h.values
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
require 'backports'
:-) - Marc-André Lafortune