0

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

Leon
  • 1,262
  • 3
  • 20
  • 41
  • What is the desired return value if the hash is `{a: {m: {b: 2, c: 1}}}`? – Cary Swoveland Dec 27 '19 at 02:25
  • ```['a.m.b', 'a.m.c']``` – Leon Dec 27 '19 at 02:58
  • See "[Stack Overflow question checklist](https://meta.stackoverflow.com/questions/260648)". We want to know what you tried. Currently it looks like you didn't try and want us to write code for you. "[Writing The Perfect Question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/)" is also useful. – the Tin Man Dec 31 '19 at 06:04
  • 1
    I posted a problem I wanted to solve. This is only a piece of the bigger function. I am not going to post the whole function here. – Leon Jan 02 '20 at 20:52
  • I find the title of the question very good. That's what the upvote is for. – schmijos May 20 '22 at 06:30

1 Answers1

3
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"]
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100