I have this list of maps (or structs) and I get a list of newly updated maps. I want to update the maps in the old list with the values from the new list. Basically I can just replace the old ones with the new ones (in my real code it’s all structs rather than maps).
This is what I came up with:
olds = [
%{class_id: 1, user_id: 1},
%{class_id: 1, user_id: 2},
%{class_id: 1, user_id: 3},
%{class_id: 1, user_id: 4},
%{class_id: 1, user_id: 5}
]
news = [
%{class_id: 1, user_id: 2, new_key: 123},
%{class_id: 1, user_id: 4, new_key: 456, another_new_key: 789}
]
# expected output
# [
# %{class_id: 1, user_id: 1},
# %{class_id: 1, user_id: 2, new_key: 123},
# %{class_id: 1, user_id: 3},
# %{class_id: 1, user_id: 4, new_key: 456, another_new_key: 789},
# %{class_id: 1, user_id: 5}
# ]
olds |> Enum.map(fn old ->
new_with_same_ids = news |> Enum.find(fn new -> new.class_id == old.class_id and new.user_id == old.user_id end)
if (new_with_same_ids != nil) do
new_with_same_ids
else
old
end
end)
|> IO.inspect
This works, but not sure it’s very efficient, as it probably traverses both lists in m*n fashion I guess.
My second attempt is much simpler:
news ++ olds |> Enum.uniq_by(fn el -> {el.class_id, el.user_id} end) |> Enum.sort_by(& &1.user_id)
|> IO.inspect
But I lose the original order and have to use sort_by
Any suggestions how to do this more efficiently, please?
Thank you very much.