Build a tree from a flat structure recursively

I would start by selecting root nodes, where parent_id is nil. Then use a recursive constructor to build children’s field.

iex> list = [
  %{id: 2, name: "Child 2", parent_id: nil},
  %{id: 1, name: "Child 1", parent_id: nil},
  %{id: 3, name: "GrandChild 1", parent_id: 1},
  %{id: 5, name: "Child 3", parent_id: nil},
  %{id: 6, name: "GrandGrandChild 1", parent_id: 3}
]
iex> new_node = fn node -> %{id: node.id, name: node.name, children: Enum.filter(list, & &1.parent_id == node.id) |> Enum.map(& new_node.(&1))} end
#Function<44.65746770/1 in :erl_eval.expr/5>
iex> Enum.filter(list, & is_nil(&1.parent_id)) |> Enum.map(& new_node.(&1))                                                                        
[
  %{children: [], id: 2, name: "Child 2"},
  %{
    children: [
      %{
        children: [%{children: [], id: 6, name: "GrandGrandChild 1"}],
        id: 3,
        name: "GrandChild 1"
      }
    ],
    id: 1,
    name: "Child 1"
  },
  %{children: [], id: 5, name: "Child 3"}
]