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.)
Here's a simple recursive solution:
def nested_hash_value(obj,key) if obj.respond_to?(:key?) && obj.key?(key) obj[key] elsif obj.respond_to?(:each) r = nil obj.find{ |*a| r=nested_hash_value(a.last,key) } r end end h = { foo:[1,2,[3,4],{a:{bar:42}}] } p nested_hash_value(h,:bar) #=> 42
No need for monkey patching, just use Hashie gem: https://github.com/intridea/hashie#deepfind
user = { name: { first: 'Bob', last: 'Boberts' }, groups: [ { name: 'Rubyists' }, { name: 'Open source enthusiasts' } ] } user.extend Hashie::Extensions::DeepFind user.deep_find(:name) #=> { first: 'Bob', last: 'Boberts' }
For arbitrary Enumerable objects, there is another extension available, DeepLocate: https://github.com/intridea/hashie#deeplocate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With