Created
December 12, 2011 18:58
-
-
Save thoughtpunch/1468577 to your computer and use it in GitHub Desktop.
A Better Way to iterate through arrays/hashes with nils?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Let say I'm getting back a JSON nested hash (or array of hashes) from an API | |
@example = {"results" = > {{"poop" => "shoop"},{"foo" => {"shizz" => "fizz", "nizzle"=>"bizzle"}}} | |
# YAML VIEW OF ABOVE | |
#- poop: shoop | |
#- foo: | |
# shizz: fizz | |
# nizzle: bizzle | |
#Now lets go make a db entry with ActiveRecord from the hash. This should work fine. | |
Thing.create!(:poop => @example["results"]["poop"], | |
:shizz => @example["results"]["foo"]["shizz"], | |
:nizzle=> @example["results"]["foo"]["nizzle"]) | |
# But what if 'foo' is empty or nil? For example, if an API result has a "person" hash with "first name","last name" # etc, the "person" hash will usually be empty if there is no data, which means the hashes inside it don't exist. | |
# such as this example: | |
@example = {"results" = > {{"poop" => "shoop"},{"foo" => nil }} | |
Thing.create!(:poop => @example["results"]["poop"], | |
:shizz => @example["results"]["foo"]["shizz"], | |
:nizzle=> @example["results"]["foo"]["nizzle"]) | |
#NoMethodError: You have a nil object when you didn't expect it! | |
#You might have expected an instance of Array. | |
#The error occurred while evaluating nil.[] | |
#What's the best way to handle this? | |
Doh, that's right, try is Rails-only. I personally wouldn't monkeypatch Hash like that. Better to create a special method that handles it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I also asked this question on SO and got the same answer, as well as a monkey patch for 'Hash' that should do the trick.
http://stackoverflow.com/questions/8479476/iterating-through-a-ruby-nested-hash-with-nils
class Hash
def get(key, default=nil)
key.split(".").inject(self){|memo, key_part| memo[key_part] if memo.is_a?(Hash)} || default
end
end
h = { 'a' => { 'b' => { 'c' => 1 }}}
puts h.get "a.b.c" #=> 1
puts h.get "a.b.c.d" #=> nil
puts h.get "not.here" #=> nil