Skip to content

Instantly share code, notes, and snippets.

@ScotterC
Created April 29, 2013 15:05
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 ScotterC/5482191 to your computer and use it in GitHub Desktop.
Save ScotterC/5482191 to your computer and use it in GitHub Desktop.
Hash deep find correction
# A common method you'll find on the internet for a deep_find in a Hash
def deep_find(key)
key?(key) ? self[key] : self.values.inject(nil) {|memo, v| memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
end
# Let's break this up without the ternarys
def deep_find(key)
if key?(key)
self[key]
else
self.values.inject(nil) do |memo, v|
if v.respond_to?(:deep_find)
memo ||= v.deep_find(key)
end
end
end
end
# The problem with the above is it can screw up badly with a hash that has values past the nested hashes
# such as:
# {:a => {:b => {:c => :stuff} }, :d => other_stuff }
# What will happen is memo will get assigned correctly but then the next inject will set memo to
# nil and the value will be lost
# A fix for this is to return memo if you got it and not spend any more time looking.
def deep_find(key)
if key?(key)
self[key]
else
self.values.inject(nil) do |memo, v|
return memo if memo
if v.respond_to?(:deep_find)
memo ||= v.deep_find(key)
end
end
end
end
# Shortened
def deep_find(key)
key?(key) ? self[key] : self.values.inject(nil) {|memo, v| return memo if memo; memo ||= v.deep_find(key) if v.respond_to?(:deep_find) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment