2016-11-27 69 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'。这不是你想要做的吗?查找是否所有按键都按正确的顺序存在,这同样重要,所以为什么要这么做呢? –