在 Ruby 中设置哈希等于另一个哈希

Posted

技术标签:

【中文标题】在 Ruby 中设置哈希等于另一个哈希【英文标题】:Setting hash equal to another hash in Ruby 【发布时间】:2012-07-15 17:53:17 【问题描述】:

我想跟踪一些任意命名的字符串的计数,然后将计数重置为零。我的想法是做以下事情:

reset_hash="string1"=>0,"string2"=>0,"string3"=>0
=> "string1"=>0, "string2"=>0, "string3"=>0 

new_hash = reset_hash
=> "string1"=>0, "string2"=>0, "string3"=>0 

new_hash["string1"]=1
new_hash["string3"]=1
new_hash
=> "string1"=>1, "string2"=>0, "string3"=>1

...

现在我想将 new_hash 重置为 reset_hash:

new_hash = reset_hash
=> "string1"=>1, "string2"=>0, "string3"=>1
reset_hash
=> "string1"=>1, "string2"=>0, "string3"=>1 

这里发生了什么?看来reset_hash实际上已经设置为new_hash,这与我想要的相反。如何实现所需的行为?

【问题讨论】:

【参考方案1】:

您正在修改单个哈希。

两个变量都引用同一个哈希。当您更改哈希中的项目时,两个引用都会反映该更改 - 因为它是相同的哈希实例。

也许您想先复制哈希?如果你这样做了,并且你有一个包含复杂对象的哈希,你还需要研究浅拷贝和深拷贝/克隆。

【讨论】:

我以为我在复制哈希。那么我该如何正确地做到这一点呢? 您正在将 reference 复制到散列;您需要使用clone (docs),注意注意事项。有很多方法可以进行深度克隆,包括仅对对象进行编组/解组。【参考方案2】:

您需要使用克隆来制作副本。

见https://***.com/a/4157438/1118101

否则,您只会创建 2 个指向同一个哈希的“指针”,而不是复制内容。

然后使用替换将克隆的内容复制回您现有的哈希中。

【讨论】:

【参考方案3】:

当你有一个指向一个对象的变量时,你实际上只是有一个对该对象的引用。如果 a 和 b 都指向哈希 1=>3, "foo" => 54,则更改 a 或 b 将更改另一个。

但是,您可以结合使用两种方法来制作您想要的东西。

哈希的默认值:

new_hash = Hash.new(0)

这为未使用的值提供了默认值 0:

new_hash["eggs"]  # -> 0

然后您可以添加计数:

new_hash["string1"] += 1 # => 1

完成后打电话

new_hash.clear # => 

并且您的哈希值将被重置,但新访问仍将默认为 0。

请注意,如果您将默认值设置为数字以外的对象类型,您可能会因为上面提到的整个参考问题而改变事物。

irb(main):031:0> b = Hash.new("Foo") #=> 
irb(main):032:0> b[3] #=> "Foo"
irb(main):033:0> b[33] #=> "Foo"
irb(main):034:0> b[33].upcase! #=> "FOO"
irb(main):035:0> b[3] # => "FOO"

要解决这个问题,您可以将一个块传递给您的哈希:

h = Hash.new |hash, key| hash[key] = "new default value"

这每次都会在 key 处创建一个新对象,因此对一个对象的更改不会产生涟漪:

d = Hash.new |hash,key| hash[key] = "string" #=> 
d[3] # => "string"
d[3].upcase! #=> "STRING"
d[5] #=> "string"

【讨论】:

【参考方案4】:

正如其他人提到的,您必须使用clone。您的任务应如下所示:

reset_hash="string1"=>0,"string2"=>0,"string3"=>0
new_hash = reset_hash.clone

new_hash["string1"]=1
new_hash["string3"]=1
new_hash

new_hash = reset_hash.clone
reset_hash

【讨论】:

以上是关于在 Ruby 中设置哈希等于另一个哈希的主要内容,如果未能解决你的问题,请参考以下文章

我尝试创建的 Ruby 方法有问题

ruby 哈希包含另一个哈希,深度检查

使用来自另一个哈希的新值更新了 Ruby 哈希数组

ruby 将哈希值转换为排序的字符串数组,以便与另一个哈希值进行比较

哈希键的Ruby值?

如何在 css 模块文件中设置非散列类的样式?