Maxim Fedotov
Maxim Fedotov

Reputation: 1357

How to return array of hashes with modified values

I've been successfully converting an array of objects into an array of hashes. But I also want to modify the objects slightly as well, before getting the combined hash.

This is what I do to convert array of objects into a combined hash:

prev_vars.map(&:to_h).reduce({}, :merge)
{ "b"=>#<Money fractional:400 currency:GBP> }

But what I want to have instead, which required to additionally call to_i is:

{ "b"=> 4 }

I got this working using this line, but I am looking for a more elegant solution:

prev_vars.map(&:to_h).reduce({}) { |combined, v| combined.merge({v.keys[0] => v.values[0].to_i}) }

Upvotes: 2

Views: 79

Answers (1)

Matthew White
Matthew White

Reputation: 363

How large is prev_vars? map(&:to_h) could require a fair amount of memory overhead, because it instantiates an entirely new array. Instead, I'd recommend switching the order: first #reduce, then #to_h:

prev_vars.reduce({}) do |combined, var|
  combined.merge! var.to_h.transform_values!(&:to_i)
end

Note the use of #merge! rather than #merge so that a new hash is not created for combined for each iteration of the loop.

Upvotes: 3

Related Questions