我有一系列音乐曲目,在这个阵列中,由于在多张专辑中发行,同一首歌可以多次显示。我试图从数组中删除它们,以便只在列表中显示真正的唯一身份。
Hash看起来像这样:
"tracks" => [
[0] {
"id" => 1,
"Title" => "Intergalactic",
"ArtistName" => "Beastie Boys"
},
[1] {
"id" => 2,
"Title" => "Intergalactic",
"ArtistName" => "Beastie Boys"
}
]
我需要一种基于Title
键删除重复项的方法。无论如何这样做?
答案 0 :(得分:11)
如果您使用的是ActiveSupport,则可以使用uniq_by,如下所示:
tracks.uniq_by {|track| track["title"]}
如果没有,那么您可以自己轻松实现它。 See this.
# File activesupport/lib/active_support/core_ext/array/uniq_by.rb, line 6
def uniq_by
hash, array = {}, []
each { |i| hash[yield(i)] ||= (array << i) }
array
end
答案 1 :(得分:9)
1.9中的Array#uniq!
方法需要一个块,所以如果你的哈希值是h
那么:
h['tracks'].uniq! { |x| x['Title'] }
如果你是1.8,那么你可以伪造它:
h['tracks'] = h['tracks'].group_by { |x| x['Title'] }.values.map(&:first)
我假设你想要就地修改它。
答案 2 :(得分:0)
虽然其他方法是正确的,但我还是会在SO的其他地方添加一些多余的糖。
使用Symbol的扩展名:
class Symbol
def with(*args, &block)
->(caller, *rest) { caller.send(self, *rest, *args, &block) }
end
end
而不是像
那样编写简单的迭代块 foo_array.each{ |foo| foo.update_bar("baz") }
,您现在可以使用
foo_array.each &:update_bar.with("baz")
类似于您写maybe_nil.try(:[], "key")
...
foo_array.uniq{ |foo| foo["key"] }
现在与
foo_array.uniq(&:[].with("key"))
我希望这对您有帮助