簡體   English   中英

如何在訪問哈希內部的哈希時處理潛在的錯誤?

[英]How to deal with potential errors while accessing a hash inside a hash?

有時在處理API響應時,我最終會寫一些類似於:

what_i_need = response["key"]["another key"]["another key 2"]

問題是,如果缺少"another key" ,它會拋出一個錯誤。 我不喜歡那樣。 我會很多快樂,如果what_i_need變成了一個nil ,如果沿着過程的東西壞了。

是否有比以下更優雅的解決方案:

what_i_need = nil
begin
  what_i_need = response["key"]["another key"]["another key 2"]
rescue Exception => e
end

我也考慮過猴子修補NilClass,你試圖訪問nil["something"]它會返回nil ,但我不確定這是否是最好的方式來解決它,如果它甚至可能。

使用帶有默認值的Hash #fetch

h = {:a => 2}
h.fetch(:b,"not present")
# => "not present"
h.fetch(:a,"not present")
# => 2

如果沒有默認值,它將拋出KeyError

h = {:a => 2}
h.fetch(:b)
# ~> -:2:in `fetch': key not found: :b (KeyError)

但是對於你可以使用的嵌套Hash你可以使用:

h = {:a => {:b => 3}}
val = h[:a][:b] rescue nil # => 3
val = h[:a][:c] rescue nil # => nil
val = h[:c][:b] rescue nil # => nil

Ruby 2.0有NilClass#to_h

what_i_need = response["key"].to_h["another key"].to_h["another key 2"]

從Objective-C的鍵值編碼系統中汲取靈感,您可以使用輕量級DSL在一個任意嵌套的數據結構中移動一系列鍵:

module KeyValue
  class << self
    def lookup(obj, *path)
      path.inject(obj, &:[]) rescue nil
    end
  end
end

h = { a: { b: { c: 42, d: [ 1, 2 ] } }, e: "test"}

KeyValue.lookup(h, :a, :b, :d, 1) # => 2
KeyValue.lookup(h, :a, :x)        # => nil

或者,如果你只想要一個班輪:

(["key", "another key", "another key 2"].inject(h, &:[]) rescue nil)

為了擴展@ Priti的答案 ,你可以使用一串 Hash#fetch而不是Hash#[]來返回空哈希,直到你到達鏈中的最后一個,然后返回nil

what_i_need = response.fetch('key', {})
                      .fetch('another key', {})
                      .fetch('another key 2', nil)

或者依賴於引發的KeyError異常(可能不是最好的,因為應該避免控制流的異常):

what_i_need = begin
                response.fetch('key').fetch('another key').fetch('another key 2')
              rescue KeyError
                nil
              end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM