0

Very similar to this question, but in Ruby.

I have a nested hash (below is a NON literal example), and I have an array that points to my deepest child value:

ab0:
  ad1:
    ab0:
      ad1: {}
ad1:
  ab0:
    ad1:
      ab0: {}

The array that points to the last key "ab0" is [1,0,0,0]. I would like to use this array to traverse the hash by pointing to hash[1][0][0][0].

I will be using this hopefully to get each key used on the path to the child in question. My result should be:

keysUsed(hash, [1,0,0,0]) = [hash.keys[1], hash.keys[1].keys[0], hash[1].keys[0].keys[0]]
7
  • 1
    You hash is not valid Ruby code. Besides, why should hash.keys[1] refer to :ab0 and not :ad1? Commented Jan 13, 2017 at 7:49
  • 1
    Maybe you could choose a different example hash, it's quite confusing to have repeating key names. Commented Jan 13, 2017 at 8:03
  • 1
    Why is the last 0 ignored? Shouldn't there be hash[1].keys[0].keys[0].keys[0] at the end? Are the keys hashes as well? Commented Jan 13, 2017 at 8:05
  • And last but not least: what's your expected result? For an input of [1,0,0,0], you have given an array with 3 (why?) elements: hash.keys[1], hash.keys[1].keys[0] and hash[1].keys[0].keys[0] but only the first one produces a result. Maybe the second element should be hash[hash.keys[1]].keys[0]? Please clarify. Commented Jan 13, 2017 at 8:08
  • The linked question creates a nested Hash from an Array. If I understand it right, you want just the opposite. I'm not even sure, since your title also describes the opposite of your question. Commented Jan 13, 2017 at 9:00

1 Answer 1

0

Array to nested Hash

Here's an answer to the question in your title and the link you provided :

def to_nested_hash(array)
  array.reverse.inject { |h, k| { k => h } }
end

hash1 = to_nested_hash([:a, :b, :c, :d])
#=> {:a=>{:b=>{:c=>:d}}}

Nested Hash to Array

def path_from_nested_hash(hash, indices)
  path = []
  indices.inject(hash){ |h, i|
    case h
    when Hash
      path << h.keys[i]
      h.values[i] || {}
    when Array
      path << h[i]
      h[i]
    else
      path << h
    end
  }
  path
end

path_from_nested_hash( hash1.merge(hash2), [0,0,0,0])
# [:a, :b, :c, :d]
path_from_nested_hash( hash1.merge(hash2), [1,0,0,0])
# [:e, :f, :g, :h]
path_from_nested_hash( hash1.merge(hash2), [1,1,0,0])
# [:e, nil, nil, nil]
Sign up to request clarification or add additional context in comments.

1 Comment

thank you! My apologies that the question wasn't super clear. However, your answer did the trick. I can now give a Hash and a Pointer array, and get an array of keys traversed to get to the pointer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.