rubyruby-2.6

Build paths of edge keys in nested hashes in ruby


I have a nested hash with multiple levels and I want to get all the possible paths of each edge key from the root as dot notation string. For example

{a: {m: {b: 2}, c: {d: {e: nil}}}}

I would like to produce an array of elements like the one below

['a.m.b', 'a.c.d.e']


Solution

  • def recurse(h)
      h.flat_map do |k,v|
        if v.is_a?(Hash)      
          recurse(v).map { |str| "%s.%s" % [k.to_s, str] }
        else
          k.to_s
        end
      end
    end
    

    h = {a: {m: {b: 2, c:1}, d: {e: {f: nil}, g: 3}}}
    recurse(h)
      #=> ["a.m.b", "a.m.c", "a.d.e.f", "a.d.g"] 
    

    h = {a: {m: {b: 2, c:1}, d: 5 }, e: {f: {g: nil}, h: 3}}
    recurse(h)
      #=> ["a.m.b", "a.m.c", "a.d", "e.f.g", "e.h"]