Stack Overflow Asked by Lucky on November 12, 2021
I am parsing some JSON which has been converted to Ruby data structures. I have records that look either like this:
"uros"=>[{"ure"=>"zip*less", "prs"=>[{"mw"=>"ˈzip-ləs", "sound"=>{"audio"=>"ziples01", "ref"=>"c", "stat"=>"1"}}]
or like this:
"uros"=>[{"ure"=>"gas chromatographic", "fl"=>"adjective"}]
I want to pull out the hash value for the key audio
when it appears.
What is the clean way to test for the presence of said key in Ruby? Here are my attempts thus far. The variable entry
represents the enclosing data structure:
if entry["uros"] != nil # Nope
#if entry["uros"]["prs"] != nil # Nope
#if not entry["uros"]["prs"]["sound"]["audio"].first.instance_of? nil # Nope
#if ! entry["uros"]["prs"].instance_of? nil # Nope
puts entry["uros"].first["prs"].first["sound"]["audio"]
end
The error message I get is either:
undefined method `first' for nil:NilClass (NoMethodError)
or conversely:
undefined method `[]' for nil:NilClass (NoMethodError)
How would you do this?
You can use the safe navigation operator to search around the the data structure without getting a bunch of NoMethodErrors. The safe navigation operator will call the method, or return nil
if called on nil
.
audio = entry["uros"]
&.first
&.[]("prs")
&.first
&.dig("sound", "audio")
This might look funny, but remember that []
is just another method. If any part of that method chain returns nil
, the whole thing will return nil
.
entry["uros"]&.first
is roughly equivalent to...
entry["uros"].first if entry["uros"] != nil
Answered by Schwern on November 12, 2021
Hash has a method for checking presence of a key-value pair
if entry.key?('uros')
But problem with your code is you don't check for existence of the nested keys. You check for "uros", but then "prs" might not exist.
Here's a better version that allows nils at every step
audio = entry.dig('uros', 0, 'prs', 0, 'sound', 'audio')
Answered by Sergio Tulentsev on November 12, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP