Comparing two lists

I am having two lists, an old one and a new one

old = [{:a, :c, 1}, {:b, :d, 2}, {:c, :a, 1}]
new = [{:a, :c, 2}, {:b, :d, 3}, {:c, :b, 1}]

I want to compare the atoms of the older one with the newer one, if the older tuple exists in a new one then only take the tuple from the new list else take both in the final output.

the final output will look something like this

final = [{:a, :c, 2}, {:b, :d, 3}, {:c, :a, 1}, {:c, :b, 1}]

i have tried it using this code but I am not able to get the correct result

Enum.map(old, fn x ->
      Enum.map(new, fn y ->
        if Tuple.delete_at(x, tuple_size(x) - 1) == Tuple.delete_at(y, tuple_size(y) - 1) do
          List.delete(old, x)        
        end
      end)
    end)

Note: {:a, :b, 1} and {:a, :b, 2} are same as we are comparing them on atoms only.

Thanks

Properly distinguishing between what is the key and what is the value should make the task quite a bit simpler:

map_old = Map.new(old, fn {a, b, c} -> {{a, b}, c} end)
map_new = Map.new(old, fn {a, b, c} -> {{a, b}, c} end)
map = Map.merge(map_old, map_new, fn _key, _v_old, v_new -> v_new end)
list = Enum.map(map, fn {{a, b}, c} -> {a, b, c} end)
2 Likes

Thanks for your response. I have modified your code and now it can support any data rather than just {a, b, c}.

def merge(old, new)  do
    Map.merge(list_to_map(old), list_to_map(new), fn _key, _v_old, v_new->
      v_new
    end)
    |> Enum.map(fn {values, integer_value} ->
      [Tuple.to_list(values), integer_value] |> List.flatten() |> List.to_tuple()
    end)
  end

  defp list_to_map(data) do
    Map.new(data, fn x ->
      {Tuple.delete_at(x, tuple_size(x) - 1), elem(row, tuple_size(x) - 1)}
    end)
  end

Note: There is nothing like Enum.to_list/2

Thanks

Thanks. I’ve corrected that one.