哈希键如何从后端递归地工作?

时间:2013-01-13 10:18:12

标签: ruby ruby-1.9.3

我正在播放哈希h1的非存在键。但是当我看到一些错误及其解决方案时,我感到很惊讶。我想知道递归调用如何在内部处理错误。

部分-I

这里尝试时h1 [2] [3]导致错误。好的,下一部分我已经解决了。

irb(main):002:0> h1=Hash.new()
=> {}
irb(main):003:0> h1[2]
=> nil
irb(main):004:0> h1[2][3]
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):4
        from C:/Ruby193/bin/irb:12:in `<main>'

部分-II

现在,Hash定义如何处理上一个错误。运行了什么内部算法,这是第一部分可能的机器人。我知道下面的sysntx解决了它,但我希望看到内部屏幕如何完成工作。

irb(main):005:0> h1 = Hash.new do |h,k|
irb(main):006:1*   h[k] = Hash.new()
irb(main):007:1> end
=> {}
irb(main):008:0> h1[2]
=> {}
irb(main):009:0> h1[2][3]
=> nil

可以修复递归调用吗?说h1 [1] [2] [3]和h1 [1] [2] [3] [4]等等。

当我通过h1 [2]呼叫Key时 - 在这里我知道2是我正在寻找的密钥。现在h1 [1] [2] - 在这种情况下呼叫寻找密钥[ 1] [2] - 我说得对吗?如果我不正确那么真实的东西是如何从后端工作的 - 想知道这一点。

有人可以帮助我理解吗?

谢谢,

2 个答案:

答案 0 :(得分:3)

h = Hash.new{|h, k| h[k] = Hash.new(&h.default_proc)}
#demo:
p h[:a][:b][:c]=1 # =>{:a=>{:b=>{:c=>1}}}

答案 1 :(得分:2)

如果我理解你的问题,我认为你可以用递归的Proc做到你想要的东西:

p = Proc.new { Hash.new { |hash, key| hash[key] = p.call } }
h = Hash.new { |hash, key| hash[key] = p.call }

然后:

h[0][0][0] -> {}

说明:

p是Ruby Proc。 Proc类似于Ruby块,但它们是完全成熟的对象,因此可以存储在变量中。

Procs可以是递归的 - 它们可以调用自己,我们在这个例子中使用它来创建一个新的默认Hash值,无论我们调用的哈希树下面有多少级别。 Proc#call方法调用Proc。请注意,Proc的主体可以访问在其范围之外定义的变量(它是一个闭包)。

steenslags解决方案或多或少地做了同样的事情,但是使用Hash#default_proc属性是一个更优雅的单线程,以避免需要定义Proc变量。