Reputation: 49
I have an array of hashes, and I want the unique values and count out of it. I have:
a = [{:key => 2}, {:key => 1}, {:key => 4}, {:key => 1}]
I want see:
a = [{:key => 2}, {:key => 1, :count =>2}, {:key => 4}]
Upvotes: 1
Views: 1978
Reputation: 513
Try this:
a.each {|h| count = a.count(h); if count > 1; dup_h = h.clone; h.merge!({:count => count}); a.delete(dup_h); end }
Upvotes: 0
Reputation: 3144
The most concise way there is (I think) is this:
a.uniq.map{|hsh| c = a.count(hsh); c == 1 || hsh[:count] = c; hsh}
or if you don't want to modify the hashes in a:
a.uniq.map{|hsh| h = hsh.dup; c = a.count(hsh); c == 1 || h[:count] = c; h}
A (marginally) prettier solution that yields a different result is:
a.uniq.group_by{|hsh| a.count(hsh)}
#=> {1=>[{:key=>2}, {:key=>4}], 2=>[{:key=>1}]}
Check out the documentation on Enumerable#count and Enumerable#group_by to learn more of what you can do with those.
Ruby's core is actually quite powerful.
Upvotes: -1
Reputation: 1484
Try this:
a = [{:key => 2}, {:key => 1}, {:key => 4}, {:key => 1}]
b = a.clone
a.uniq!
a.inject([]) { |result,h| h[:count]=b.count(h) if b.count(h) > 1 ; result << h; result }
=> [{:key=>2}, {:key=>1, :count=>2}, {:key=>4}]
Upvotes: 2
Reputation: 11957
You will just have to iterate over the array and count how many times each key occurs, and then sum it all together by building a new array with the result.
The below code snippet should do it.
a = [{:key => 2}, {:key => 1}, {:key => 4}, {:key => 1}]
counts = Hash.new(0)
a.map do |item|
counts[item[:key]] += 1
end
a = counts.collect do |key, count|
if count > 1
{:key => key, :count => count}
else
{:key => key}
end
end
Upvotes: 1