为什么在合并另一个哈希时更新嵌套哈希的所有值



我有以下哈希:

hash = {2021=>{:gastosCompra=>0}, 2022=>{:gastosCompra=>0}, 2023=>{:gastosCompra=>0}}

创建如下

headers = {
gastosCompra: 'gastos compra',
}
elements = headers.inject({}) { |h, (k, _v)| h[k] = 0; h }
hash = Hash[years.collect { |item| [item, elements] }]

我正在尝试更新key year 2021gastosCompra。我试过mergedeep_merge,但不幸的是,所有其他密钥也都更新了:

hash[year][:gastosCompra] = 555
hash[year].merge!({gastosCompra: 555})
hash[year].deep_merge!({gastosCompra: 555})

这就是结果:

hash = {2021=>{:gastosCompra=>555}, 2022=>{:gastosCompra=>555}, 2023=>{:gastosCompra=>555}}

如果我只想更新2021年,为什么所有嵌套的哈希都会更新?我想当我找到2021年的时候,我可以在钥匙上循环,然后停下来,但我想避免这种情况。

所有对象的对象Id都是相同的,您必须制作elements哈希的副本。

他们都指的是同一个地址。

红宝石中有一个浅黄色的副本,带有:

Object#dup:https://ruby-doc.org/core-3.0.3/Object.html#method-i-dup

hash = Hash[years.collect { |item| [item, elements.dup] }]

Kernel#clone:https://ruby-doc.org/core-3.0.3/Kernel.html#method-i-clone

您也可以使用ActiveSupport进行深度复制:https://api.rubyonrails.org/classes/Hash.html#method-i-deep_up

仅供参考->请参阅Ruby Marshal类,它在某些情况下很有用:https://ruby-doc.org/core-3.0.3/Marshal.html

最新更新