How can I solve that recursive problem?

I have a data structure like this:

list = [
  %{
    name: "cherry",
    list: [
      %{
        name: "apple",
        list: [
          %{
            name: "pear",
            list: []
          },
          %{
            name: "pineapple",
            list: [
              %{
                name: "mango",
                list: []
              }
            ]
          }
        ]
      },
      %{
        name: "kiwi",
        list: [
          %{
            name: "orange",
            list: [
              %{
                name: "raspberry",
                list: []
              },
              %{
                name: "banana",
                list: []
              },
            ]
          }
        ]
      }
    ]
  },
  %{
    name: "strawberry",
    list: []
  }
]

I need to convert it in a list of lists like below for that example:

[
  ["cherry", "apple", "pear"],
  ["cherry", "apple", "pineapple", "mango"],
  ["cherry", "kiwi", "orange", "raspberry"],
  ["cherry", "kiwi", "orange", "banana"],
  ["strawberry"]
]

You can see that each element in the list is kind of a “branch” of those maps that form like a tree.

I have tried today but I can’t figure it out :sob:

Even a small pseudo-code, or an idea, can help, thank you.

Just use recursion

def build(list) when is_list(list) do
  Enum.flat_map(list, &extract/1)
end

defp extract(%{name: name, list: []}), do: [[name]]

defp extract(%{name: name, list: children}) do
  for child <- children,
      rest <- extract(child) do
    [name | rest]
  end
end
6 Likes

Thank you @hauleth !!

Can’t figure out though why [[name]] must be returned here.
At some point it will be appended to the list here:
[name | rest]

But indeed if I replace [[name]] by [name] then I get an improper list:
["cherry", "apple", "pineapple" | "mango"]

Because we are iterating over each entry in the rest <- extract(child) and append to list in rest. If we return just [name] then we will try to make tail of the list out of name which will result with improper list.

2 Likes