1

Should be quick one! Couldn't quite find the exact query elsewhere:

I have a hash in the form:

{"Chicago"=>[35.0, 5.0, 7.0], "Austin"=>[12.0, 42.0, 15.0, 8.0], ... }

I simply want to sum the numbers within the hash's value (array) to become:

{"Chicago"=> 47.0, "Austin"=> 77.0, ... }

I have tried sum and inject (hash.values.each.inject(0) { |sum, x| sum + x} etc.) and am met with "Array cannot be coerced into Integer" exceptions, and I'm not sure the correct way to go about this, though it seems a relatively simple ask!

2 Answers 2

5

Take a look at Hash#transform_values. Also you can replace inject with Array#sum.

hash.transform_values(&:sum)

Sign up to request clarification or add additional context in comments.

1 Comment

That's the ticket. I haven't used transform_values before and didn't catch it when skimming through the doc - thank you very much!
2

Following your original approach, here is a full working solution -- it looks like you were on the right lines!

hash = {"Chicago"=>[35.0, 5.0, 7.0], "Austin"=>[12.0, 42.0, 15.0, 8.0]

hash.map { |city, values| [city, values.inject(0){ |sum, value| sum + value}] }.to_h

Phew! But that looks a bit complicated! Luckily for starters, you can call inject with a symbol that names an operator to shorten it a little:

hash.map { |city, values| [city, values.inject(:+)] }.to_h

Or even better, you can call Array#sum to achieve the same thing in this case:

hash.map { |city, values| [city, values.sum] }.to_h

We can still do better, though. For this very common use-case of only needing to transform hash values, whilst preserving the overall hash structure, modern ruby has a builtin method for this called ... you guessed it, transform_values:

hash.transform_values { |values| values.sum }

And finally, simplifying this one last time:

hash.transform_values(&:sum)

1 Comment

Very helpful! Thanks for taking the time to go through it!

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.