Hmm. In that case, doing clever Radix-based solutions are out.
In this case I would already say that appending these two lists would be a bad idea, since this takes linear time based on the size of the first list.
My shot:
defmodule Foo do
@doc """
Combines two lists whose values are both supposed to be maps or structs that have an `.id`-field.
Merges each of these maps/structs when they have the same `.id`,
and returns the result as a list ordered by the `.sort`-field
that these maps/structs are also expected to have.
"""
def combine_lists_of_maps_with_same_ids(list_a, list_b) do
Map.merge(list_to_id_map(list_a), list_to_id_map(list_b), fn _, map1, map2 ->
Map.merge(map1, map2)
end)
|> Map.values
|> Enum.sort_by(&(&1.sort))
end
@doc """
Turns a list whose fields are maps or structs that have an `.id`-field,
into a map where the keys are the values of these `.id`-fields.
"""
def list_to_id_map(input) do
for x = %{id: id} <- input, into: %{}, do: {id, x}
end
end
Your version leaves in records that have id and sort but do not have name, and I was left with the impression that the OP does not want that. (My code only leaves those records that have all 3 fields after a merge.)