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 })