为什么我不能将newer
组合到older
?
def update_inventory(older, newer)
newer.each {|x, y| older[x] += y}
end
update_inventory({rubies: 10, emeralds: 14, diamonds: 2}, {emeralds: 27, moonstones: 5})
未定义方法 +' 表示
nil:NilClass
(重复(:2:在update_inventory
块中 (重复(:2:在each
(重复(:2:在update_inventory
(重复(:5:<main>
它无法按预期工作,因为older
不包含newer
中的所有键。
newer
由两个键值对组成: {emeralds: 27, moonstones: 5}
因此newer.each
将调用块{ |x, y| ... }
两次:
-
在第一次迭代中,
x
:emeralds
,y
27
工作正常,因为它具有:emeralds
的值older
:older[:emeralds] #=> 14 older[:emeralds] += 27 #=> 41
-
在第二次迭代中,
x
:moonstones
,y
5
,因此得到:older[:moonstones] #=> nil older[:moonstones] += 5 #=> NoMethodError: undefined method `+' for nil:NilClass
该错误是由于 Ruby 尝试计算
nil + 5
而nil
没有+
方法(因此"nil:NilClass 的未定义方法'+'"(。
若要解决此问题,可以添加一个条件来检查密钥是否存在。但是有一个更简单的方法:Hash#update
完全符合您的需求:
def update_inventory(older, newer)
older.update(newer) { |_, v1, v2| v1 + v2 }
end
它会将键值对从newer
复制到older
。如果两个哈希中都存在一个键,则将调用该块来确定新值。
older = {rubies: 10, emeralds: 14, diamonds: 2}
newer = {emeralds: 27, moonstones: 5})
older.update(newer) { |_, v1, v2| v1 + v2 }
#=> {:rubies=>10, :emeralds=>41, :diamonds=>2, :moonstones=>5}