当前位置:  开发笔记 > 后端 > 正文

Uniq by Ruby中的object属性

如何解决《UniqbyRuby中的object属性》经验,为你挑选了6个好方法。

选择数组中对于一个或多个属性唯一的对象的最优雅方法是什么?

这些对象存储在ActiveRecord中,因此使用AR的方法也可以.



1> 张健健..:

使用Array#uniq带块:

@photos = @photos.uniq { |p| p.album_id }


您可以使用to_proc(http://www.ruby-doc.org/core-1.9.3/Symbol.html#method-i-to_proc)改进它:`@ photos.uniq&:album_id`
这是[ruby 1.9](http://ruby-doc.org/core-1.9.2/Array.html#method-i-uniq)及更高版本的正确答案.
+1.而对于早期的红宝石,总会有"需要'后退'.":-)

2> Daniel Lucra..:

uniq_by方法添加到项目中的Array.它的作用类似于sort_by.所以,uniq_byuniqsort_bysort.用法:

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!方法,但如果您愿意,它应该很容易.

编辑: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


这个答案已经过时了.Ruby> = 1.9有一个Array#uniq,其中一个块就是这样,就像在接受的答案中一样.

3> mislav..:

在数据库级别上执行:

YourModel.find(:all, :group => "status")



4> 小智..:

您可以使用此技巧从数组中的几个属性元素中选择唯一:

@photos = @photos.uniq { |p| [p.album_id, p.author_id] }



5> Alex M..:

我原本建议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.

不过,我不确定你的目的是什么.



6> Head..:

我喜欢jmah使用Hash来强制执行唯一性.这里有几种皮肤猫的方法:

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

这是一个不错的1-liner,但我怀疑这可能会更快一点:

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

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有