Skip to content

prefer_any_or_every

v0.1.0 Warning Fix Collection & Type

Flags .where(predicate).isNotEmpty and .where(predicate).isEmpty. Both build a lazy Iterable only to ask a yes/no question that any and every answer directly, stopping at the first decisive element. The quick fix rewrites it.

isNotEmpty after a where is any written out:

class Invoice {
const Invoice({required this.isOverdue, required this.isPaid});
final bool isOverdue;
final bool isPaid;
}
bool hasOverdueInvoice(List<Invoice> invoices) {
return invoices.where((invoice) => invoice.isOverdue).isNotEmpty;
}
class Invoice {
const Invoice({required this.isOverdue, required this.isPaid});
final bool isOverdue;
final bool isPaid;
}
bool hasOverdueInvoice(List<Invoice> invoices) {
return invoices.any((invoice) => invoice.isOverdue);
}

any returns as soon as one invoice matches. The where form still has to build the iterable and ask it whether it produced anything.

isEmpty is every, with the predicate flipped

Section titled “isEmpty is every, with the predicate flipped”

This is where the rewrite needs care: “nothing matches p” is “everything matches not p”, so the predicate has to be negated, not copied.

// Don't — no invoice is unpaid
bool isFullySettled(List<Invoice> invoices) {
return invoices.where((invoice) => !invoice.isPaid).isEmpty;
}
// Do
bool isFullySettled(List<Invoice> invoices) {
return invoices.every((invoice) => invoice.isPaid);
}

Only where is matched. .map(...).isNotEmpty and .whereType<T>().isNotEmpty are not reported, since neither has an any/every equivalent that keeps the same meaning.

The where must take exactly one argument, and its receiver must resolve to an Iterable. A dynamic receiver is left alone.

length > 0 is not matched. Only the isEmpty and isNotEmpty getters are, so items.where(p).length > 0 passes — though any is the better call there too.

See also: Iterable.any | Iterable.every

This rule is in the recommended preset, so it is on with preset: recommended or preset: opinionated. Add it to preset: core with prefer_any_or_every: true.

To turn it off:

many_lints.yaml
rules:
prefer_any_or_every: false

To keep the rule on but skip certain paths, use per-rule exclude.