开发者

Ruby removing duplicates from array based on key=>value

开发者 https://www.devze.com 2023-04-11 01:05 出处:网络
I have an array of Musical Tracks and in this array the same song can show up multiple times due to being released on multiple albums. I am trying to remove them开发者_如何转开发 from the array so tha

I have an array of Musical Tracks and in this array the same song can show up multiple times due to being released on multiple albums. I am trying to remove them开发者_如何转开发 from the array so that only true uniques show up in the list.

The Hash looks something like this:

"tracks" => [
    [0] {
        "id" => 1,
        "Title" => "Intergalactic",
        "ArtistName" => "Beastie Boys"
    },
    [1] {
        "id" => 2,
        "Title" => "Intergalactic",
        "ArtistName" => "Beastie Boys"
    }
]

I am needing a way to remove the duplicates based on the Title key. Anyway of doing this?


If you are using ActiveSupport, you can use uniq_by, like so :

tracks.uniq_by {|track| track["title"]}

If not, then you can easily implement it yourself. 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


The Array#uniq! method in 1.9 takes a block so if your Hash is h then:

h['tracks'].uniq! { |x| x['Title'] }

If you're in 1.8 then you can fake it with:

h['tracks'] = h['tracks'].group_by { |x| x['Title'] }.values.map(&:first)

I'm assuming that you want to modify it in-place.


While the other methods are correct, I'll throw in a bit of extra sugar I found elsewhere on SO.

Using this extension of Symbol:

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

Instead of writing simple iterative blocks like

foo_array.each{ |foo| foo.update_bar("baz") }, you can now use

foo_array.each &:update_bar.with("baz")

Similar to how you might write maybe_nil.try(:[], "key")...

foo_array.uniq{ |foo| foo["key"] } is now identical to

foo_array.uniq(&:[].with("key"))

I hope this helps

0

精彩评论

暂无评论...
验证码 换一张
取 消