Easily Extract Deeply Nested Hash Data in Ruby
Dealing with deeply nested hashes can be a huge pain, but it doesn't need to be.
We’ve all been in the situation where you obtain data in a hash and need to extract some value. For example, you have the following hash, and need to get the innermost value:
hash = { first: { second: { third: 'value' } } }You could try:
hash[:first][:second][:third] #=> 'value'However, what happens when a nil is encountered along the way?
hash = {}
hash[:first][:second][:third] #=> NoMethodError: undefined method `[]' for nil:NilClassThrowing an exeption may not be what you want. If you have access to ActiveSupport you could use the try method:
hash.try(:[], :first).try(:[], :second).try(:[], :third) #=> 'value'
Now, I like the try method, but this is truly an abomination.
Enter Hash#dig
As of Ruby 2.3.0, the Hash#dig method makes this so much easier. Take a look!
1
2
3
4
5
hash = { first: { second: { third: 'value' } } }
hash.dig(:first, :second, :third) #=> 'value'
hash = { first: { second: nil } }
hash.dig(:first, :second, :third) #=> nil
If a nil is encountered at any level, then nil is returned.
Note that this also works for
Array
and
Struct
, although I’m not sure they are as useful as the Hash method:
array = [[['value']]]
array.dig(0, 0, 0) #=> 'value'