Keep list of entries during Enum.map

I am trying to update a field in a map if a previous map in a list has the same editor_id.

My function is,

defp mark_duplicate_editor_entries(entry_list) do
    seen_editors = []

    Enum.map(entry_list, fn entry ->
      case Enum.member?(seen_editors, entry.editor_id) do
        true ->
          %{entry | duplicate_editor: true}

        false ->
          seen_editors = seen_editors ++ [entry.editor_id]
          entry
      end
    end)
  end

The (probably very obvious) issue is that I cannot update seen_editors from within the Enum.map

Where am I going wrong or what’s the alternative?

You can use reduce and keep your list in the acc https://hexdocs.pm/elixir/Enum.html#reduce/3 also take a look at dedup with a callback https://hexdocs.pm/elixir/Enum.html#dedup_by/2

1 Like

When looking for “is something true for the next/prev item” you can always look at Enum.zip and using the same list with the first/last element striped as second list.

1 Like

I hope this code does what you want :slight_smile:

  Enum.map_reduce(entry_list, [], fn entry, seen_editors ->
    if entry.editor_id in seend_editors do
      {%{entry | duplicate_editor: true}, seen_editors}
    else
      {entry, [entry.editor_id | seen_editors]}
    end
  end)

Thanks @fuelen, that’s perfect, got me back on track.