我已经看到了很多关于这个的问题,但只有一个键,从不用于多个键.
我有以下哈希数组:
a = [{:name=>"Yes,Yes,Yes",:artist=>"Some Dude",:composer=> 'First Dude',:duration=>"3:21"},{:name=>"Chick on the Side",:artist=>"Another Dude",:duration=>"3:20"},{:name=>"Luv Is",:duration=>"3:13"},{:name=>"Yes,:duration=>"2"},:artist=>"Another Dude"}]
a.uniq在这里不起作用,因为持续时间不同或甚至不存在.我在数据库中设置了一个唯一的密钥,不允许使用相同名称,艺术家和作曲家的重复条目,因此当人们对这3个密钥有重复的条目时,我有时会遇到错误.
有没有办法运行uniq来检查这3个键?我试过像这样的块:
new_tracks.uniq do |a_track| a_track[:name] a_track[:artist] a_track[:composer] end
但是忽略了密钥不存在的任何东西(没有作曲家的任何条目都不符合上述标准).
我总是可以使用:name键,但这意味着我将摆脱具有相同标题但不同的艺术家或作曲家的编辑中的潜在有效曲目.
这是Ruby 2.0.
解决方法
uniq
接受一个区块.如果给出了一个块,它将使用块的返回值进行比较.
您的代码接近解决方案,但在您的代码中,返回值只是a_track [:composer],这是最后一次计算的语句.
您可以将所需的属性加入到字符串中并返回该字符串.
new_tracks.uniq { |track| [track[:name],track[:artist],track[:composer]].join(":") }
可能的重构是
new_tracks.uniq { |track| track.attributes.slice('name','artist','composer').values.join(":") }
class Track < ActiveRecord::Base def digest attributes.slice('name','composer').values.join(":") end end new_tracks.uniq(&:digest)