Hi,
Can I ask whether if there’s a smart way to convert a list of struct to map, then update certain property of that converted list based on another list of map with same id.
For example
poll_options = [
%Pickr.Polls.Option{
__meta__: #Ecto.Schema.Metadata<:loaded, "options">,
id: 23,
inserted_at: ~N[2020-10-24 06:16:47],
poll: #Ecto.Association.NotLoaded<association :poll is not loaded>,
poll_id: 6,
updated_at: ~N[2020-10-24 06:16:47],
value: "A"
},
%Pickr.Polls.Option{
__meta__: #Ecto.Schema.Metadata<:loaded, "options">,
id: 24,
inserted_at: ~N[2020-10-24 06:16:47],
poll: #Ecto.Association.NotLoaded<association :poll is not loaded>,
poll_id: 6,
updated_at: ~N[2020-10-24 06:16:47],
value: "B"
},
%Pickr.Polls.Option{
__meta__: #Ecto.Schema.Metadata<:loaded, "options">,
id: 25,
inserted_at: ~N[2020-10-24 06:16:47],
poll: #Ecto.Association.NotLoaded<association :poll is not loaded>,
poll_id: 6,
updated_at: ~N[2020-10-24 06:16:47],
value: "C"
}
],
Then the existing list of map
%{option_id: 23, votes: 1}]
What I want is to merge the two maps into this one. if the 1st list does not have the id in the 2nd list, the votes property will be set to 0
[
%{option_id: 23, votes: 1},
%{option_id: 24, votes: 0},
%{option_id: 25, votes: 0}
]
I can achieve the same result above with my code below
defp append_votes_with_defaults(options, result) do
options
|> set_default_votes()
|> remove_options_with_votes(result)
|> append_votes_to_default_votes(result)
end
defp set_default_votes(options) do
Enum.map(options, fn option ->
%{option_id: option.id, votes: 0}
end )
end
defp remove_options_with_votes(options, result) do
Enum.reject(options, fn opt ->
Enum.any?(result, fn res ->
opt.option_id == res.option_id
end)
end)
end
defp append_votes_to_default_votes(options, result) do
options ++ result
end
I’m just asking if there’s a shorter or efficient way to achieve the same result.
If there’s an unclear part, please let me know so I can add further information.
Thank you very much.