2013-01-13 52 views
0

我玩到散列不存在關鍵h1.but了驚訝,當我看到一些錯誤,並與他們resolution.I想知道如何遞歸調用做的工作在內部處理的錯誤。哈希鍵查找如何從後端遞歸地工作?

部分-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

現在怎麼下面的哈希定義處理以前的錯誤。運行什麼內部算法,這是第一部分可能實現的。我知道下面的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]調用密鑰時 - 這裏我知道2是我正在尋找的密鑰。現在h1 [1] [2] - 在這種情況下,尋找密鑰的呼叫[1] [ 2] - 我正確嗎?如果我不正確,那麼真實的東西是如何從後端工作的 - 想知道這一點。

誰能幫我在這裏明白了嗎?

感謝,

回答

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。 Procs與Ruby塊類似,但是是完全成熟的對象,因此可以存儲在變量中。

特效可以遞歸 - 他們可以稱自己和我們做在這個例子中使用的,要無論創建新的默認的Hash值多少級下來,我們稱之爲散列的樹。 Proc#call方法調用Proc。請注意,Proc的主體可以訪問在其範圍外定義的變量(它是一個閉包)。

steenslags解決方案是做或多或少同樣的事情,而是一個更優雅的一行代碼利用了Hash#default_proc財產,以避免需要定義一個Proc變量。

+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}}} 
+0

能否請你解釋一下,你的代碼如何運行你的例子,打破它的每一部分! –

+0

它是遞歸的。這不是我的想法 - 我在某處找到了它,可能是Rubytalk。 Hash.new之後的塊定義了在哈希中未找到密鑰時應該發生的情況-AKA默認proc。在這裏,我們定義應該創建一個新的散列作爲新鍵的新值。這個新的散列還有一個塊,用於定義未知密鑰應該發生什麼情況,這恰好與我們定義的默認過程相同。 – steenslag