Is there a better way to traverse a tree structure and accumulate leaves than this code?
def traverse_start(value, acc_list) when is_list(value) do
for v <- value, reduce: acc_list do
acc -> acc ++ traverse(v, acc_list)
end
|> Enum.uniq()
end
def traverse_start(value, acc_list) when is_map(value) do
for {k, v} <- value, reduce: acc_list do
acc -> acc ++ traverse([k], v, acc_list)
end
|> Enum.uniq()
end
def traverse(keys, value, acc_list) when is_map(value) do
# keys |> IO.inspect
for {k, v} <- value, reduce: acc_list ++ [keys] do
acc -> acc ++ traverse(keys ++ [k], v, acc)
end
end
def traverse(keys, value, acc_list) when is_list(value) do
# keys |> IO.inspect
for v <- value, reduce: acc_list ++ [keys] do
acc -> (acc ++ traverse(keys, v, acc)) |> Enum.uniq()
end
end
def traverse(keys, _value, _acc_list) do
# keys |> IO.inspect
[keys]
end
This code traverses a map or list and gets a list of unique paths. It’s used to get column names for a CSV file from an array of JSON documents.
columns = Report.traverse_start(data_list, []) |> Enum.sort()
input
data_list = [
%{},
%{
"a" => 1,
"b" => %{"bb" => 2},
"c" => %{"cc" => %{"ccc" => 3}},
"n" => nil,
"u" => %{"uu" => nil},
"w" => %{"ww" => %{"www" => nil}},
"r" => [],
"z" => %{}
},
%{
"a" => 1,
"b" => %{"bb" => 2},
"c" => %{"cc" => %{"ccc" => 3}},
"n" => nil,
"u" => %{"uu" => nil},
"w" => %{"ww" => %{"www" => nil}},
"r" => [
%{
"a" => 1,
"b" => %{"bb" => 2},
"c" => %{"cc" => %{"ccc" => 3}},
"n" => nil,
"u" => %{"uu" => nil},
"w" => %{"ww" => %{"www" => nil}},
"r" => [
%{
"a" => 1,
"b" => %{"bb" => 2},
"c" => %{"cc" => %{"ccc" => 3}},
"n" => nil,
"u" => %{"uu" => nil},
"w" => %{"ww" => %{"www" => nil}},
"r" => [],
"z" => %{}
},
%{
"d" => 4
}
],
"z" => %{}
},
%{
"d" => 4
}
]
}
]
output
columns = [
["a"],
["b"],
["b", "bb"],
["c"],
["c", "cc"],
["c", "cc", "ccc"],
["n"],
["r"],
["r", "a"],
["r", "b"],
["r", "b", "bb"],
["r", "c"],
["r", "c", "cc"],
["r", "c", "cc", "ccc"],
["r", "d"],
["r", "n"],
["r", "r"],
["r", "r", "a"],
["r", "r", "b"],
["r", "r", "b", "bb"],
["r", "r", "c"],
["r", "r", "c", "cc"],
["r", "r", "c", "cc", "ccc"],
["r", "r", "d"],
["r", "r", "n"],
["r", "r", "r"],
["r", "r", "u"],
["r", "r", "u", "uu"],
["r", "r", "w"],
["r", "r", "w", "ww"],
["r", "r", "w", "ww", "www"],
["r", "r", "z"],
["r", "u"],
["r", "u", "uu"],
["r", "w"],
["r", "w", "ww"],
["r", "w", "ww", "www"],
["r", "z"],
["u"],
["u", "uu"],
["w"],
["w", "ww"],
["w", "ww", "www"],
["z"]
]