2

I am working on Ruby on Rails project using rails4.

Scenario:

I have an array of hashes. An array contains hashes where keys are the same.

 a = [{132=>[1000.0]}, {132=>[4000.0]}, {175=>[1000.0]}, {175=>[1000.0]}, {133=>[1200.0]}]
 h = a.each {|key,value| key.each {|k| value}}
#{132=>[1000.0]}
#{132=>[4000.0]}
#{175=>[1000.0]}
#{175=>[1000.0]}
#{133=>[1200.0]}

Problem:

How to get rid off duplicate keys but with values added to unique keys like this:

 {132=>[1000,4000]}
 {175=>[1000,1000]}
 {133=>[1200]}

Thank you.

0

3 Answers 3

7

That would do it:

a.inject({}) {|sum, hash| sum.merge(hash) {|_, old, new| old + new }}
Sign up to request clarification or add additional context in comments.

Comments

6

This works for me:

p a.each_with_object(Hash.new([])) { |e, h| e.each { |k, v| h[k] += v } }

# => {132=>[1000.0, 4000.0], 175=>[1000.0, 1000.0], 133=>[1200.0]}

3 Comments

Thank you, I will think it through.
Do you mean that you like the possibility to avoid a condition by set a default hash value?=). Or you are hinting that it could be done another way?
I didn't express myself well, but what I meant is that I liked Hash.new([]) and h[k] += v better than what I thought to be the main alternative: Hash.new {|h,k| h[k]=[]} and h[k] << v.first. On reflection, however, the former may be less efficient, as a new array is created when each element is added. Hmmm. Would you mind doing an edit, so I can roll back my +1?. Actually, (h[k] ||= []) <<... probably would be quite a bit faster yet. (Nix the edit request. :-) ).
2

Another way:

a.each_with_object({}) do |g,h|
  k, v = g.to_a.flatten
  (h[k] ||= []) << v
end
  #=> {132=>[1000.0, 4000.0], 175=>[1000.0, 1000.0], 133=>[1200.0]}

or

a.each_with_object(Hash.new { |h,k| h[k]=[] }) do |g,h|
  k, v = g.to_a.flatten
  h[k] << v
end
  #=> {132=>[1000.0, 4000.0], 175=>[1000.0, 1000.0], 133=>[1200.0]}

1 Comment

Nice approach as usual.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.