我已经看到了很多与此有关的问题,但是只有一个键,而从来没有多个键。

我有以下散列数组:

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/

10-16 19:30