sut*_*tee 118 ruby arrays ruby-on-rails unique
选择数组中对于一个或多个属性唯一的对象的最优雅方法是什么?
这些对象存储在ActiveRecord中,因此使用AR的方法也可以.
张健健*_*张健健 192
使用Array#uniq带块:
@photos = @photos.uniq { |p| p.album_id }
Run Code Online (Sandbox Code Playgroud)
Dan*_*aft 22
将uniq_by方法添加到项目中的Array.它的作用类似于sort_by.所以,uniq_by是uniq的sort_by是sort.用法:
uniq_array = my_array.uniq_by {|obj| obj.id}
Run Code Online (Sandbox Code Playgroud)
实施:
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
Run Code Online (Sandbox Code Playgroud)
请注意,它返回一个新数组,而不是修改当前的数组.我们还没有编写uniq_by!方法,但如果您愿意,它应该很容易.
编辑:Tribalvibes指出该实现是O(n ^ 2).更好的是(未经测试)......
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
Run Code Online (Sandbox Code Playgroud)
mis*_*lav 17
在数据库级别上执行:
YourModel.find(:all, :group => "status")
Run Code Online (Sandbox Code Playgroud)
小智 11
您可以使用此技巧从数组中的几个属性元素中选择唯一:
@photos = @photos.uniq { |p| [p.album_id, p.author_id] }
Run Code Online (Sandbox Code Playgroud)
我原本建议select在Array上使用该方法.以机智:
[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使用Hash来强制执行唯一性.这里有几种皮肤猫的方法:
objs.inject({}) {|h,e| h[e.attr]=e; h}.values
Run Code Online (Sandbox Code Playgroud)
这是一个不错的1-liner,但我怀疑这可能会更快一点:
h = {}
objs.each {|e| h[e.attr]=e}
h.values
Run Code Online (Sandbox Code Playgroud)
小智 5
将Array#uniq与块一起使用:
objects.uniq {|obj| obj.attribute}
Run Code Online (Sandbox Code Playgroud)
或者更简洁的方法:
objects.uniq(&:attribute)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
49063 次 |
| 最近记录: |