Contains Over Filter

ID

swift.contains_over_filter

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Efficiency

Language

Swift

Tags

collection, efficiency

Description

Reports .filter(…​).count compared with 0 (in either direction). .filter(…​) materialises the whole filtered collection; .contains(where:) short-circuits on the first match.

xs.filter { $0 > 5 }.count > 0          // FLAW
xs.filter { $0 < 0 }.count == 0         // FLAW
xs.filter { $0 > 5 }.count != 0         // FLAW

xs.contains(where: { $0 > 5 })          // OK
!xs.contains(where: { $0 < 0 })         // OK

Rationale

For "any matches?" / "no matches?" existence checks, .contains(where:) is O(k) (where k is the position of the first match) instead of O(N) for .filter(…​). The intent is also clearer.

Remediation

// any matches
let hasAny = xs.contains(where: { $0 > 5 })

// no matches
let hasNone = !xs.contains(where: { $0 < 0 })