I am trying to materialize all paths that occur in an arbitrarily-deep document, with no known keys.
Here’s an example on play.crystal-lang.org
https://play.crystal-lang.org/#/r/a7ey
---
Sports:
- Footall:
- Trophy:
- Vince Lombardi
- Teams:
- Packers:
- QB:
- Aaron Rogers
- Vikings:
- QB:
- Kirk Cousins
- Sean Mannion
- Hockey:
- Teams:
- Bruins
- Canadiens
- Trophy:
- Stanley Cup
Desired output:
[["Sports", "Footall", "Trophy", "Vince Lombardi"],
["Sports", "Footall", "Teams", "Packers", "QB", "Aaron Rogers"],
["Sports", "Footall", "Teams", "Vikings", "QB", "Kirk Cousins"],
["Sports", "Footall", "Teams", "Vikings", "QB", "Sean Mannion"],
["Sports", "Hockey", "Teams", "Bruins"],
["Sports", "Hockey", "Teams", "Canadiens"],
["Sports", "Hockey", "Trophy", "Stanley Cup"]]
Here’s what I came up with:
def recurse_yaml(input : YAML::Any, path = [] of String, result = [] of Array(String)) : Array(Array(String))
if (hash_input = input.as_h?)
hash_input.each do |key, val|
recurse_yaml(val, path + [key.as_s], result)
end
elsif (array_input = input.as_a?)
array_input.each do |el|
recurse_yaml(el, path, result)
end
elsif (string_input = input.as_s?)
result << (path + [string_input])
end
result
end
I hate that there’s so much logic, and looping in some of the if conditions. This just doesn’t seem right. Is there a better way to accomplish this?
Thank you, and I absolutely love the language, thank you all for an absolutely amazing bit of tech!