当要汇总哈希集合中单个键的值时,我通常从构造一个计数哈希开始:
h = (a+b+c).each_with_object({}) do |g,h|
h[g[:name]] = (h[g[:name]] || 0) + g[:value]
end
#=> {"Identifier"=>1500, "Identifier2"=>150}
请注意,如果h没有键g[:name], h[g[:name]] #=> nil,则:
h[g[:name]] = (h[g[:name]] || 0) + g[:value]
= (nil || 0) + g[:value]
= 0 + g[:value]
= g[:value]
我们现在可以很容易地得到想要的结果:
h.map { |(name,value)| { name: name, value: value } }
#=> [{:name=>"Identifier", :value=>1500},
# {:name=>"Identifier2", :value=>150}]
如果需要,可以链接这两个表达式:
(a+b+c).each_with_object({}) do |g,h|
h[g[:name]] = (h[g[:name]] || 0) + g[:value]
end.map { |(name,value)| { name: name, value: value } }
#=> [{:name=>"Identifier", :value=>1500},
# {:name=>"Identifier2", :value=>150}]
有时您可能会看到:
h[k1] = (h[k1] || 0) + g[k2]
书面:
(h[k1] ||= 0) + g[k2]
它扩展到同样的事情。
下面是另一种计算方法h,我会说它更像“Ruby-like”。
h = (a+b+c).each_with_object(Hash.new(0)) do |g,h|
h[g[:name]] += g[:value]
end
这将使用Hash::newh的形式创建由块变量表示的哈希,该形式接受一个称为默认值的参数:
h = Hash.new(0)
这意味着如果h没有 key k,h[k]则返回默认值,here 0。注意
h[g[:name]] += g[:value]
扩展为:
h[g[:name]] = h[g[:name]] + g[:value]
因此,如果h没有密钥g[:name],则减少为:
h[g[:name]] = 0 + g[:value]
如果你想知道为什么h[g[:name]]等式左边没有被替换0,那是因为表达式的那部分使用了方法Hash#[]=,而右边使用了方法Hash#[] 。Hash::new只关注默认值Hash#[]。