I have this method
def heights
(60..68).reduce({}) { |h, i| h.merge!( { %(#{i/12}'#{i%12}") => i } ) }
end
it returns a hash of heights
{
"5'0\"" => 60, "5'1\"" => 61, "5'2\"" => 62,
"5'3\"" => 63, "5'4\"" => 64, "5'5\"" => 65,
"5'6\"" => 66, "5'7\"" => 67, "5'8\"" => 68
}
That's what I want. However, I don't like using the merge! method. I'd much rather use the hash[key] = value syntax for assignment:
def heights
(60..68).reduce({}) { |h, i| h[%(#{i/12}'#{i%12}")] = i }
end
But this code throws errors. I know that with reduce, in your pipes you can name your accumulator and element.
I also understand that
sum = 0
(1..5).each { |i| sum += i }
is equivalent to
(1..5).reduce(0) { |sum, i| sum + i }
So why doesn't this
hash = {}
(1..5).each { |i| hash[i.to_s] = i }
work the same as
(1..5).reduce({}) { |hash, i| hash["#{i}"] = i }
You could use each_with_object instead of reduce:
(60..68).each_with_object({}) { |i, h| h[%(#{i/12}'#{i%12}")] = i }
enumerable.each_with_object(obj) { ... } returns obj so you don't need the artificial-feeling ; h in the block that you'd need with reduce.
Note that the order of the arguments to the block is different than with reduce.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With