Combine two list with maps

Hi, please can you help me with the next question. I want to combine two lists with maps, the idea is to combine the maps by id.

list1 = [
  %{name: Oranges, id: 4, quantity: 1},
  %{name: Apples, id: 6, quantity: 2}
]

list2 = [
  %{count: 1, id: 4}
]

The results is:

[
  %{name: Oranges, id: 4, quantity: 1, count: 1},
  %{name: Apples, id: 6, quantity: 2}
]

Are the ID’s unique in both lists or only one of the other or can there be duplicates anywhere, and if so how do they merge if conflicting data?

1 Like

You could solve that with group_by(enumerable, key_fun, value_fun \ fn x -> x end) in combination with Map.merge(map1, map2, fun).
And as @OvermindDL1 already mentioned you need to decide how to merge conflicting data. (That can be done in the merge function)

1 Like

I’m sorry, I restate the problem:

list1 = [
  %{name: Oranges, list1_id: 4, quantity: 1},
  %{name: Apples, list1_id: 6, quantity: 2}
]

list2 = [
  %{count: 1, list2_id: 4}
]

The results is:

[
  %{name: Oranges, list1_id: 4, quantity: 1, count: 1, list2_id: 4},
  %{name: Apples, list1_id: 6, quantity: 2}
]
iex(1)> Enum.map(list1, fn m -> Map.merge(m, Enum.find(list2, %{}, &(&1[:list2_id] == m[:list1_id]))) end)
[
  %{count: 1, list1_id: 4, list2_id: 4, name: Oranges, quantity: 1},
  %{list1_id: 6, name: Apples, quantity: 2}
]
2 Likes
Enum.map(list1, fn %{list1_id: id} = m -> 
  list2 |> Enum.find(%{}, &match?(%{list2_id: ^id}, &1)) |> Map.merge(m) end
)

Edit: haha @pma you beat me by that much!

2 Likes

Thanks’ pma, great solution

Thank’s Greg for your contribution, God bless you