Merging 2 nested maps

Hello guys, I have a maybe dumb question but I’m trying without success to merge 2 maps with nested values

%{"XX" => %{"A" => 1}} %{"XX" => %{"B" => 3}, "YY" => %{"A" => 2}} and the expected result is

%{"XX" => %{"A" => 1, "B" => 3}, "YY" => %{"A" => 2}}

but map1 |> Map.merge(map2) only merge the root keys

any idea?

2 Likes

You need to use Map.merge/3 and provide a conflict handler that handles the conflicts recursively.

4 Likes

Awesome

solved with

 result = ma1 |> Map.merge(map2, fn _k, v1, v2 ->
      v1 |> Map.merge(v2)
    end)

ty so much @NobbZ !!

4 Likes

I was looking for information on maps that might have more nesting and couldn’t find anything. I came up with this and hope it helps others also searching for that:

def merge_nested(map1, map2) do
  Map.merge(map1, map2, &merge_nested/3)
end

def merge_nested(_k, %{} = v1, %{} = v2) do
  Map.merge(v1, v2, &merge_nested/3)
end
def merge_nested(_k, _v1, v2), do: v2

For example:

a = %{a: %{b: %{c: 1}}}
b = %{a: %{b: %{d: 2}}}

merge_nested(a, b)
#> %{a: %{b: %{c: 1, d: 2}}}
1 Like

You may also be interested in deep_merge:

4 Likes