by June 20, 2018

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'
Curtis Miller

Curtis Miller

Managing Partner

Startup junkie, Rubyist and gamer. Loves to brainstorm about new ideas.

Need help with your project?

We specialize in Ruby on Rails and JavaScript projects. Code audits, maintenance and feature development on existing apps, or new application development. We've got you covered.

Get in touch!