我有一个音乐曲目数组,在这个数组中,由于在多个专辑中发布,同一首歌曲可以多次显示。我试图从数组中删除它们,以便只有真正的唯一显示在列表中。
哈希看起来像这样:
"tracks" => [
[0] {
"id" => 1,
"Title" => "Intergalactic",
"ArtistName" => "Beastie Boys"
},
[1] {
"id" => 2,
"Title" => "Intergalactic",
"ArtistName" => "Beastie Boys"
}
]
我需要一种方法来删除基于Title
键的重复项。怎么做呢?
如果你正在使用activessupport,你可以使用uniq_by,像这样:
tracks.uniq_by {|track| track["title"]}
如果没有,那么您可以自己轻松实现它。看到这个。
# 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中的Array#uniq!
方法需要一个块,所以如果你的哈希值是h
,那么:
h['tracks'].uniq! { |x| x['Title'] }
如果你是在1.8版本,那么你可以用:
h['tracks'] = h['tracks'].group_by { |x| x['Title'] }.values.map(&:first)
我假设你想就地修改它
虽然其他方法都是正确的,但我将在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"))
希望对大家有所帮助