Reputation: 79
I have below array which has to sum up same keys values as {'dogs' => 11, 'cats' => 3}.
animals = [['dogs', 4], ['cats', 3], ['dogs', 7]]
I have found the below answer while I was searching on stackoverflow (I lost the link:( )
print animals.each_with_object(Hash.new(0)) { |(k, v), h| h[k] += v }
However I can't make it clear in my mind that what do k,v and h represents exactly. Because "h" is staying second argument of the block code but it continious with h[k] . Could anyone explain the code clearly?
Thank you too much.
Upvotes: 0
Views: 835
Reputation: 121000
animals.map(&:dup).
group_by(&:shift).
map { |k, v| [k, v.flatten.inject(:+)] }.
to_h
#⇒ {"dogs"=>11, "cats"=>3}
Upvotes: 2
Reputation: 29144
Playing around with the Array to understand it better
animals.each {|arr| puts arr.inspect }
# ["dogs", 4]
# ["cats", 3]
# ["dogs", 7]
animals.each {|k, v| puts "k -> #{k}, v -> #{v}" }
# k -> dogs, v -> 4
# k -> cats, v -> 3
# k -> dogs, v -> 7
animals.each_with_object({}) do |(k, v), h|
puts "k -> #{k}, v -> #{v}, h -> #{ h.inspect }"
end
# k -> dogs, v -> 4, h -> {}
# k -> cats, v -> 3, h -> {}
# k -> dogs, v -> 7, h -> {}
animals.each_with_object({}) do |(k, v), h|
h[v] = k
puts "k -> #{k}, v -> #{v}, h -> #{ h.inspect }"
end
# k -> dogs, v -> 4, h -> {4=>"dogs"}
# k -> cats, v -> 3, h -> {4=>"dogs", 3=>"cats"}
# k -> dogs, v -> 7, h -> {4=>"dogs", 3=>"cats", 7=>"dogs"}
Upvotes: 1
Reputation: 211670
In simple terms:
animals.each_with_object(Hash.new(0)) do |(key, value), hash|
hash[key] += value
end
Here (k,v)
is an expansion of each pair in the animals
hash, which is key-value. h
represents the "object" that's passed along with this iteration.
That's a fairly standard pattern in terms of Ruby code.
Upvotes: 3