Skip to content

Instantly share code, notes, and snippets.

@ibanez270dx
Last active August 22, 2019 06:32
Show Gist options
  • Save ibanez270dx/1a8e11fde89c842b62404f013667323b to your computer and use it in GitHub Desktop.
Save ibanez270dx/1a8e11fde89c842b62404f013667323b to your computer and use it in GitHub Desktop.
Hash#digtect extension
class Hash
# Hash#digtect is a convenient way to find deeply nested values in a hash hierarchically.
# I.E., it returns the first present (not nil or empty string) diggable value from a
# specified list of keys. Think of it as a combination of Hash#dig and Hash#detect.
#
# Given the following Hash object:
#
# hash = {
# "deeply": { "nested": { "property": "string" } },
# "array": [ { name: "" }, { name: "foobar" }, { name: "default" } ]
# }
#
# hash.dig("not", "present").presence || hash.dig("deeply", "nested", "property").presence
# => "string"
#
# can be rewritten more concisely as:
#
# hash.digtect "not/present", "deeply/nested/property"
# => "string"
#
# ...also works with integers when specifying nested array indices:
#
# hash.digtect "array/0/name", "array/1/name", "array/2/name"
# => "foobar"
#
def digtect(*keys)
keys.each do |key|
value = begin
dig(*key.split("/"))
rescue TypeError
# try again, but replace quoted integers (array indices) w/ actual integers
dig(*key.split("/").map! do |prop|
prop.match?(/^\d+$/) ? prop.to_i : prop
end)
end
return value if value.present?
end
nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment