How to merge two keyword lists?

I am having a keyword list that I want to merge. let’s say we have the following keyword list:

list_1 = [c: [t: [c: ["id_1"]]]]
list_2 =  [
   c: [
     t: [
       c: ["id_1"],
       c: [
         {:b, "id_2", 1},
         {:b, "id_1", 1}
       ]
     ]
   ]

When i merge them using Keyword.merge(list_1, list_2) then i get the right result and that is

[
   c: [
     t: [
       c: ["id_1"],
       c: [
         {:b, "id_2", 1},
         {:b, "id_1", 1}
       ]
     ]
   ]

but let’s say if we have two lists

list_1 = [c: [t: [c: ["id_1"]]]]
list_2 = [c: [t: [c: ["id_2"]]]]

Then after Keyword.merge(list_1, list_2) then we get this result

[c: [t: [c: ["id_2"]]]]

which should be

c: [t: [c: ["id_1", "id_2"]]]]

which I have achieved through

Keyword.merge(c, p, fn _k, v1, v2 -> Enum.sort(v1 ++ v2) end)

I really don’t know how to get these two features (when a similar key value is found then replace it with a unique value while appending when they are different) in a single block of code.

Any help will be really appreciated.

Not the best code. But maybe a step in the right direction:

iex(1)> l1 = [c: [t: [c: ["id_1"]]]]
[c: [t: [c: ["id_1"]]]]
iex(2)> l2 = [c: [t: [c: ["id_2"]]]]
[c: [t: [c: ["id_2"]]]]
iex(3)> defmodule Foo do
...(3)>   def merge(a,b) do
...(3)>     Keyword.merge(a, b, fn _key, x, y ->
...(3)>       if Keyword.keyword?(x) && Keyword.keyword?(y), do: merge(x, y), else: Enum.sort(x ++ y)
...(3)>     end)
...(3)>   end
...(3)> end
{:module,...}
iex(4)> Foo.merge(l1, l2)
[c: [t: [c: ["id_1", "id_2"]]]]
4 Likes

It makes sense now… it’s working perfectly.