3

I have hash deep nested hash and i want the hierarchy(parent to child) for each key as an array.

for example -

 hash = {
"properties"=>{
    "one"=>"extra",
    "headers"=>{
        "type"=>"object",
        "type1"=>"object2"
    },
    "entity"=>{
        "type"=>"entype"
    },       
},
"sec_prop"=>"hmmm"
}

for this hash I want output as given below, as a separate array for each key.

[properties,one]
[properties,headers,type]
[properties,headers,type1]
[properties,entity,type]
[sec_prop]

i have been trying and searching this for so long through some recursive methods but it doesn't seems to work for me any help will be appreciated.

important thing to notice here is there are duplicate keys in the same hash as a nesting for example type key is repeated in both headers and entity. so that i need proper hierarchy to identify the proper key

and i should get this array of hierarchy only for those keys whose value is not a another hash.

It should be in the format above given but any other solutions also welcome

thanks.!

5
  • 3
    what's the logic for this [properties,sec_prop] ? Commented Mar 11, 2014 at 17:25
  • sorry, i didn't get that ? Commented Mar 11, 2014 at 17:34
  • -1 and close vote because the logic for [properties,sec_prop] is not clear. Commented Mar 11, 2014 at 17:36
  • I suspect an error in either the input or the output data: sec_prop is not nested under properties in the input data, but it is in the output data. Commented Mar 11, 2014 at 17:39
  • 2
    You say you've been trying, but you don't show us any code. It's easier for us to fix your attempt than it is to write something unrelated to your code and you shoehorn it in. Commented Mar 11, 2014 at 17:48

2 Answers 2

5

Recursion to the rescue:

def hashkeys(o, keys = [], result = [])
  if o.is_a?(Hash)
    o.each do |key, value|
      hashkeys(value, keys + [key], result)
    end
  else
    result << keys
  end
  result
end

This is a depth first search which accumulates keys until it gets to a leaf (a non-Hash value). Each time it get to a leaf, it adds the accumulated keys to the result.

pp hashkeys(hash)
# => [["properties", "one"],
# =>  ["properties", "headers", "type"],
# =>  ["properties", "headers", "type1"],
# =>  ["properties", "entity", "type"],
# =>  ["sec_prop"]]
Sign up to request clarification or add additional context in comments.

5 Comments

I don't know, how you code it.. I am still connectionless. :(
@Arup, I'll improve the answer, if I can. Is there any one thing that confuses you the most?
No.. Your code is perfect.. I was not able to understand what OP's logic is. This part [properties,sec_prop].
@Arup, Oh, that. Yes. I decided it must be a mistake in his question. The incorrect indentation of the input hash would make such a mistake easier.
@WayneConrad +1 You have written the code as succinct as it can get.
1

Here is my try :

hash = {
  "properties"=>{
    "one"=>"extra",
    "headers"=>{
      "type"=>"object",
      "type1"=>"object2"
    },
    "entity"=>{
      "type"=>"entype"
    },       
  },
  "sec_prop"=>"hmmm"
}

def fetch_keys(h)
  h.flat_map do |k,v|
    if v.is_a?(Hash)
      fetch_keys(v).map do |keys|
        [k] + Array(keys)
      end
    else
      k
    end
  end
end

fetch_keys(hash)
# => [["properties", "one"],
#     ["properties", "headers", "type"],
#     ["properties", "headers", "type1"],
#     ["properties", "entity", "type"],
#     "sec_prop"]

1 Comment

Note: I think it can be re-factored to some extent. So welcome all viewer advice on this..

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.