A web service is returning a hash that contains an unknown number of nested hashes, some of which contain an array, which in turn contains an unknown number of nested hashes.
Some of the keys are not unique -- i.e. are present in more than one of the nested hashes.
However, all the keys that I actually care about are all unique.
Is there someway I can give a key to the top-level hash, and get back it's value even if the key-value pair is buried deep in this morass?
(The web service is Amazon Product Advertising API, which slightly varies the structure of the results that it gives depending on the number of results and the search types permitted in each product category.)
A variation of barelyknown's solution: This will find all the values for a key in a hash rather than the first match.
{a: [{b: 1}, {b: 2}]}.deep_find(:b)
will return[1, 2]
Combining a few of the answers and comments above:
Ruby 2.3 introduces Hash#dig, which allows you to do:
Here's a simple recursive solution:
Because Rails 5 ActionController::Parameters no longer inherits from Hash, I've had to modify the method and make it specific to parameters.
If the key is found, it returns the value of that key, but it doesn't return an ActionController::Parameter object so Strong Parameters are not preserved.
No need for monkey patching, just use Hashie gem: https://github.com/intridea/hashie#deepfind
For arbitrary Enumerable objects, there is another extension available, DeepLocate: https://github.com/intridea/hashie#deeplocate