我已经看到了很多与此有关的问题,但是只有一个键,而从来没有多个键。
我有以下散列数组:
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, Yes, Yes", :artist=>"Some Dude", :composer=> 'First Dude', :duration=>"2"},
{:name=>"Chick on the Side", :artist=>"Another Dude"}]
a.uniq
在这里不起作用,因为持续时间不同或什至不存在。我在数据库中设置了唯一的 key ,该 key 不允许使用相同名称,艺术家和 Composer 进行重复输入,因此当人们对这三个键重复输入时,有时会出现错误。有没有一种方法可以运行
uniq
来检查这三个键? 我尝试了一个像这样的块: new_tracks.uniq do |a_track|
a_track[:name]
a_track[:artist]
a_track[:composer]
end
但这会忽略不存在 key 的任何内容(例如,没有 Composer 的任何条目都不符合上述条件)。
我总是可以只使用
:name
键,但这意味着我将在标题相同但艺术家或 Composer 不同的作品中摆脱潜在有效的音轨。这是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', 'artist', 'composer').values.join(":")
end
end
new_tracks.uniq(&:digest)
关于ruby-on-rails - Ruby删除哈希数组中的重复条目,但基于多个值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20566016/