[英]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.