Velocity Labs

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:NilClass

Throwing 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'

Need help with your app?

We build custom software, rescue apps that are stuck, and keep them running. Tell us what you're dealing with.