Skip to content

Instantly share code, notes, and snippets.

@tombh
Created June 18, 2013 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tombh/5807167 to your computer and use it in GitHub Desktop.
Save tombh/5807167 to your computer and use it in GitHub Desktop.
When you're accessing deep keys within a hash you don't want to have to write stuff like `if foo && foo["bar"] && foo["bar"]["baz"] && foo["bar"]["baz"]["bang"]`. So here's an idea to have a method on the Hash class that uses a sort of XML type query, eg; hash.quiet_fetch('a/b/c')
class Hash
def quiet_fetch query
current = self
query.split('/').each do |key|
if current.fetch(key, false)
current = current.fetch(key)
else
return nil
end
end
return current
end
end
hash = {
"a" => {
"b" => {
"c" => "hi"
}
}
}
puts hash.quiet_fetch "a/b/c"
# => "hi"
@nicalpi
Copy link

nicalpi commented Jun 18, 2013

Looks like there are multiple solutions (http://stackoverflow.com/questions/4371716/looking-for-a-good-way-to-avoid-hash-conditionals-in-ruby/4380514#4380514) but my preferred is using inject

class Hash
def get_deep(*fields)
fields.inject(self) {|acc,e| acc[e] if acc.is_a?(Hash)}
end
end

Clean and simple
hash.get_deep("a","b","c")

@tombh
Copy link
Author

tombh commented Jun 18, 2013

Bingo! That's exactly the answer I was looking for. Using the * for args, that's the proper way to do it. And then making a one liner for the actual drilling down into the nested hashes, genius :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment