2016-11-27 8 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 («результаты поиска», «ответ», «результаты», «результат», «zpid»)) => false – pjw23

+0

Рассмотрим 'h = {: a => {: c => {: d => 1},: b => 2}} 'и вам нужно значение в h [: a] [: b] [: d]'. Здесь h [: a] [: b] [: d] # => NoMethodError: undefined method '[] 'для nil: NilClass' (потому что' h [: a] [: b] # => nil', поэтому ' nil [: d] 'вызывает исключение). Однако все три ключа: ': a',': b' и ': d' находятся в хэше. Ясно, что вы не можете просто определить, присутствуют ли отдельные ключи.Мой ответ возвращает желаемый результат, когда все клавиши присутствуют, в правильном порядке и 'nil' в противном случае. Разве это не то, что вы хотите сделать? Это так же много работы, чтобы найти, все ли ключи присутствуют в правильном порядке, так зачем беспокоиться об этом? –