Ruby - 验证哈希密钥存在

时间:2016-11-27 04:48:40

标签: ruby hash nested verify

我在使用嵌套哈希时遇到问题并希望得到一些帮助。我正在使用的数据如下所示:

    => {"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

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

由于评论,我终于能够理解挖掘方法的语法。一切正常,因为我需要......谢谢!

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

1 个答案:

答案 0 :(得分:2)

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

正如@muistooshort在评论中指出的那样,如果你使用Ruby v2.3 +,可以在这里使用Hash#dig

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