Credence.Pattern.NoFilterThenCount (credence v0.7.0)

Copy Markdown

Detects Enum.filter/2 piped into length/1 or Enum.count/1, which creates an unnecessary intermediate list.

Why this matters

Enum.filter/2 produces a new list, then length/1 (or Enum.count/1) traverses it to count elements. Enum.count/2 with a predicate does both in a single pass without allocating the intermediate list:

# Flagged — allocates intermediate list
numbers
|> Enum.filter(fn x -> rem(x, 2) == 0 end)
|> length()

# Better — single pass, no intermediate list
Enum.count(numbers, fn x -> rem(x, 2) == 0 end)

Flagged patterns

  • Enum.filter(predicate) piped into length/1 or Enum.count/1
  • length(Enum.filter(enum, predicate))
  • Enum.count(Enum.filter(enum, predicate))

Not flagged

  • Enum.filter(pred) alone (no following count/length)
  • Enum.count(enum, pred) (already idiomatic)
  • length(enum) without preceding filter