我正在尝试创建一个 HashHash-es。第二级哈希的值是一个整数默认为0。我要做的是从空的哈希斯开始,然后当我添加一个值时,如果键不存在,则应添加它们键具有默认值。

当我简单地尝试一下 Hash 在整数上,它可以正常工作:

irb(main):003:0> h = Hash.new(0)
=> {}
irb(main):004:0> h[1] += 1
=> 1
irb(main):005:0> p h
{1=>1}
=> nil
irb(main):006:0> h.keys.size
=> 1
irb(main):007:0>

h 现在有一个钥匙,值为1。完美。

但是,当我的哈希值是哈希时,它似乎不起作用:

irb(main):007:0> h = Hash.new(Hash.new(0))
=> {}
irb(main):008:0> h[1][1] += 1
=> 1
irb(main):009:0> p h
{}
=> nil
irb(main):010:0> h.keys.size
=> 0
irb(main):011:0>

我是在做错什么吗,还是不能将哈希的默认值设置为 Hash.new(0)?

编辑:

根据下面的答案,我能够弄清楚自己做错了什么。实际上,我能够弄清楚我的想法是错误的。长话短说, h[1][1] 不筑巢 Hash.new 电话,除非你给 Hash.new 一个代码块。表达的价值 h[1][1] += 11 不出所料,但只有最内向的哈希被正确初始化。

我之所以发布此内容,是因为我上面使用了二维哈希,但我的实际问题使用了三维哈希:

syms[level][exchange][symbol] = count

该解决方案可能有助于他人遇到这个问题,因此,以下是使我想要的方式工作的代码:

irb(main):024:0> syms = Hash.new{|h1,k1| h1[k1] = Hash.new{|h2,k2| h2[k2] = Hash.new(0)}}
=> {}
irb(main):026:0> syms["level1"]["NYSE"]["IBM"] += 1
=> 1
irb(main):027:0> p syms
{"level1"=>{"NYSE"=>{"IBM"=>1}}}
=> nil
irb(main):028:0>
有帮助吗?

解决方案

创建哈希时,设置默认值的最通用方法是使用block参数使用哈希#新函数:

h = Hash.new { |h, k| h[k] = Hash.new(0) }

您遇到的问题是,您将默认值设置为对象指针而不是要执行的代码。也就是说,每当访问“外部”哈希中缺少值时,它都会返回指针 完全相同的 目的。为了向自己证明这一点,请尝试以下方法:

>> h = Hash.new(Hash.new(0))
=> {}
>> h[1] === h[2]
=> true

那么你 能够 实际上,设置哈希的默认值,但是这样做不会完成您想要的东西。增加H [1] [1]实际上将更改默认哈希本身,因为H [1]尚未初始化。

希望这可以帮助。

其他提示

h = Hash.new(Hash.new(0))

Hash.new(0)是默认对象;这是每个非键的对象。这就是哈希不存在时的哈希返回。

h = Hash.new{|h,k| h[k]=Hash.new(0)}

{| h,k | h [k] = hash.new(0)}是默认的proc。当钥匙不存在时,它会运行 新的 每个不存在的密钥的哈希(默认为0)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top