Gaurav Ingalkar
Gaurav Ingalkar

Reputation: 1277

need help in getting nested ruby hash hierarchy

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.!

Upvotes: 3

Views: 1030

Answers (2)

Arup Rakshit
Arup Rakshit

Reputation: 118299

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"]

Upvotes: 1

Wayne Conrad
Wayne Conrad

Reputation: 108269

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"]]

Upvotes: 5

Related Questions