2016-11-27 50 views
1

我遇到了嵌套散列問題,希望得到一些幫助。我正在使用的數據如下所示:Ruby - 驗證散列鍵存在

=> {"searchresults"=> 
    {"request"=>{"address"=>"10 Tiverton Ln", "citystatezip"=>"28803"}, 
    "message"=>{"text"=>"Request successfully processed", "code"=>"0"}, 
    "response"=> 
    {"results"=> 
     {"result"=> 
     {"zpid"=>"5620805"}} 

我試圖從哈希中獲取特定信息。我遇到的問題是:如果散列鍵不存在,它會拋出錯誤並殺死我的腳本。

爲了重新調解這個問題,我想我會事先覈實關鍵的存在,但是,我的支票似乎沒有正常工作。我正在使用「密鑰?」方法,但我顯然做了錯誤的事情,因爲在我的驗證(當鑰匙在那裏)導致Ruby的「錯誤」返回。

hash["searchresults"]["response"]["results"]["result"]["zpid"] 
=> "5620805" 
hash.key?("searchresults""response""results""result""zpid") 
=> false 

(注:我意識到最後的輸入只是基於評論一個連接字符串,但不能得到任何組合的工作,見下文,轉向後的底部)

什麼是最好的在查詢不存在的散列鍵時避開錯誤的方法?如果「鑰匙?」方法是正確的方法去做,有人可以請我指出我的錯誤是在哪裏的正確方向。


根據回覆添加了信息。我使用的紅寶石

ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux] 

以下版本的我終於能理解挖掘方法的語法感謝comments.Everything工作,因爲我需要...謝謝!

hash.dig("searchresults", "response", "results", "result", "zpid") 
    => "5620805" 
+0

您正在使用哪個版本的Ruby?較新的有['Hash#dig'](http://ruby-doc.org/core-2.3.3/Hash.html#method-i-dig)可能對您有用。 –

+0

讀者不能使用您的示例來測試解決方案,因爲它不是有效的Ruby對象。這裏給出了散列的一部分,但將其作爲有效散列非常簡單。此外,無論何時您舉例,請顯示您想要的輸出併爲每個輸入對象分配一個變量(例如'h = {「searchresults」=> ...}')。後者允許讀者在回答和評論中引用這些變量(這裏是'h'),而不必定義它們。另外,請編輯'pry(main)>'。除了分心之外,每個剪切和粘貼該代碼的讀者如果不這樣做,都必須將其刪除。 –

回答

2
h = { "searchresults"=> 
     { "request" =>{ "address"=>"10 Tiverton Ln", "citystatezip"=>"28803" }, 
      "message" =>{ "text"=>"Request successfully processed", "code"=>"0" }, 
      "response"=>{ "results"=>{ 
            "result"=>{ "zpid"=>"5620805" } 
            } 
         } 
     } 
    } 

由於@muistooshort在評論中指出,Hash#dig可以在這裏如果你正在使用Ruby V2.3 +使用。

h.dig("searchresults") 
    #=> {"request"=>{"address"=>"10 Tiverton Ln", "citystatezip"=>"28803"}, 
    # "message"=>{"text"=>"Request successfully processed", "code"=>"0"}, 
    # "response"=>{"results"=>{"result"=>{"zpid"=>"5620805"}}}} 
h.dig("searchresults", "response") 
    #=> {"results"=>{"result"=>{"zpid"=>"5620805"}}} 
h.dig("searchresults", "response", "results") 
    #=> {"result"=>{"zpid"=>"5620805"}} 
h.dig("searchresults", "response", "results", "result") 
    #=> {"zpid"=>"5620805"} 
h.dig("searchresults", "response", "results", "result", "zpid") 
    #=> "5620805" 

h.dig("searchresults", "cat", "results") 
    #=> nil 
h.dig("searchresults", "response", "results", "result", "dog") 
    #=> nil 

對於早期版本的Ruby,你可以使用Enumerable#reduce(又名inject)。

def my_dig(h, *keys) 
    keys.reduce(h) { |g,k| g && g[k] } 
end 

my_dig(h, "searchresults") 
    #=> {"request"=>{"address"=>"10 Tiverton Ln", "citystatezip"=>"28803"}, 
    # "message"=>{"text"=>"Request successfully processed", "code"=>"0"}, 
    # "response"=>{"results"=>{"result"=>{"zpid"=>"5620805"}}}} 
my_dig(h, "searchresults", "response") 
    #=> {"results"=>{"result"=>{"zpid"=>"5620805"}}} 
my_dig(h, "searchresults", "response", "results") 
    #=> {"result"=>{"zpid"=>"5620805"}} 
my_dig(h, "searchresults", "response", "results", "result") 
    #=> {"zpid"=>"5620805"} 
my_dig(h, "searchresults", "response", "results", "result", "zpid") 
    #=> "5620805" 

my_dig(h, "searchresults", "cat", "results") 
    #=> nil 
my_dig(h, "searchresults", "response", "results", "result", "zpid", "dog") 
    #=> nil 
+0

感謝您的回覆,我已將詳細信息添加到原始帖子中,希望能夠澄清事情。從上面使用你的信息,我似乎仍然在犯錯誤。 pry(main)> hash.dig(「searchresults」,「response」,「results」,「result」,「zpid」) =>「5620805」 pry(main)> hash.key?(hash.dig( 「searchresults」,「response」,「results」,「result」,「zpid」)) => false – pjw23

+0

考慮'h = {:a => {:c => {:d => 1},:b => 2}}'並且您希望h [:a] [:b] [:d]'處的值。這裏h [:a] [:b] [:d]#=> NoMethodError:undefined方法'[]'爲nil:NilClass'(因爲h [:a] [:b]#=> nil',所以' nil [:d]'引發例外)。然而,所有三個鍵,':a',':b'和':d'都在哈希中。顯然,你不能確定是否存在個別密鑰。當所有鍵都按正確的順序存在時,我的答案返回所需的結果,否則返回'nil'。這不是你想要做的嗎?查找是否所有按鍵都按正確的順序存在,這同樣重要,所以爲什麼要這麼做呢? –