Credence.Pattern.NoManualEnumUniq (credence v0.4.5)

Copy Markdown

Performance and idiomatic code rule: warns when Enum.uniq/1 is manually reimplemented using Enum.reduce/3 and MapSet.

Lists are deduplicated most efficiently using the built-in Enum.uniq/1 or Enum.uniq_by/2, which are implemented natively.

The fix also strips orphaned pipeline steps that were part of the manual pattern — specifically |> elem(0) / |> elem(1) (which extracted the list from the {list, MapSet} accumulator) and |> Enum.reverse() (which reversed the prepended list). Since Enum.uniq/1 returns a plain list in insertion order, both steps become unnecessary after the replacement.

Bad

Enum.reduce(list, {MapSet.new(), []}, fn item, {seen, acc} ->
  if MapSet.member?(seen, item) do
    {seen, acc}
  else
    {MapSet.put(seen, item), [item | acc]}
  end
end)

# or in a pipeline with downstream tuple extraction:
list
|> Enum.reduce({[], MapSet.new()}, fn x, {results, tracked} ->
  unless MapSet.member?(tracked, x) do
    {[x | results], MapSet.put(tracked, x)}
  else
    {results, tracked}
  end
end)
|> elem(0)
|> Enum.reverse()

Good

Enum.uniq(list)