I have a nested dict in elixir, from which I want to save the latest items in a new dict.
sorted_slides = [
%{
id: 1,
visual_events: [
%{entity_id: 1, payload: "abc"},
%{entity_id: 2, payload: "def"}
]
},
%{
id: 2,
visual_events: [
%{entity_id: 2, payload: "yui"},
%{entity_id: 3, payload: "def"},
%{entity_id: 4, payload: "ghi"},
]
},
%{
id: 3,
visual_events: [
%{entity_id: 2, payload: "ert"},
%{entity_id: 4, payload: "poi"},
]
}
]
dict = %{}
Enum.each(sorted_slides, fn slide ->
Enum.each(slide.visual_events, fn ve ->
eid = ve.entity_id
dict = Map.put(dict, eid, ve)
IO.inspect(dict)
end)
end)
IO.inspect(dict)
My original data structure contains items that may be overwritten by newer items. I want the new dict
to be:
dict = %{
1 => %{entity_id: 1, payload: "abc"},
2 => %{entity_id: 2, payload: "ert"},
3 => %{entity_id: 3, payload: "def"},
4 => %{entity_id: 4, payload: "poi"}
}
I want the dict
to save the changes made to it by each iteration, but I guess that scoping works different from some other languages here.
How would I achieve this in Elixir?
You can use Enum.flat_map/2
to extract the inner elements, and Map.new/2
to construct a new map from those elements. Map.new/2
will ensure the latest element prevails when there are duplicate keys.
sorted_slides
|> Enum.flat_map(fn %{visual_events: items} -> items end)
|> Map.new(fn %{entity_id: id} = map -> {id, map} end)
Result:
%{
1 => %{entity_id: 1, payload: "abc"},
2 => %{entity_id: 2, payload: "ert"},
3 => %{entity_id: 3, payload: "def"},
4 => %{entity_id: 4, payload: "poi"}
}