1

Let's consider this as our hash c = {:test => {:foo => true}}

Normally, if we would like to print value of foo, we would access the hash like this c[:test][:foo] but I would like to access it dynamically based on my variable.

Therefore, let's consider the following variable path = [[:test],[:foo]].

How do I access the value true now? I have tried c[path] but it just says nil. What am I missing?

1
  • 1
    Why is your path variable a nested array? Commented Feb 28, 2018 at 13:36

2 Answers 2

3

You can make use of dig. You can check the doc of dig here Hash#dig

c = { :test => { :foo => true } }
c[:test][:foo]
#=> true

c.dig(:test, :foo)
#=> true

path = [:test, :foo]
c.dig(*path)
#=> true

You just need to pass the hierarchy

Note: The * before path in c.dig(*path) is reffered as splat operator

Sign up to request clarification or add additional context in comments.

3 Comments

Their path is [[:test],[:foo]], not [:test, :foo].
It's a variable which can be changed.
Any way we just need to add flatten if the input value is [[:test],[:foo]]
2

Old good recursive Ruby 1.9+ solution:

hash = {:test => {:foo => true}}
path = [[:test],[:foo]]

path.flatten.reduce(hash) { |h, p| h[p] }
#⇒ true

Or, as @Stefan suggested in comments:

path.reduce(hash) { |h, (p)| h[p] }
# or even
path.reduce(hash) { |h, p| h[p.first] }

More defensive:

path.flatten.reduce(hash) { |h, p| h.nil? ? nil : h[p] }

1 Comment

You can avoid flatten via path.reduce(hash) { |h, (p)| h[p] }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.