prefer-iterable-every

Same as prefer_iterable_every in Pyramid Lint

Path
lint/complexity/prefer-iterable-every
Default
On (recommended)
Origin
Pyramid Lint
Rule
380 of 512
recommended

Flags iterable.where(predicate).isEmpty and filtered-length comparisons.

An empty filtered iterable means every element fails the predicate. Prefer iterable.every((element) => !predicate(element)) to express that condition directly. When a filtered length equals the original iterable's length, use iterable.every(predicate) instead. Both forms can stop at the first failure. Only resolved SDK Iterable.where calls are checked. Length comparisons require the same simple receiver or explicit this field on both sides.

Invalid

example.dartdart
// Bad: filtered emptiness means every item fails the predicate.
void validateItems(List<int> items) {
  if (items.where((x) => x > 0).isEmpty) {
    print('No items are positive');
  }
}

// Bad: .where().length == list.length pattern
void checkAllValid(List<String> values) {
  bool allNonEmpty = values.where((v) => v.isNotEmpty).length == values.length;
  if (allNonEmpty) {
    print('All strings are non-empty');
  }
}

// Bad: the predicate must be negated when replacing filtered emptiness.
void processCollection() {
  final data = [2, 4, 6, 8];
  final allOdd = data.where((n) => n % 2 == 0).isEmpty;
}

// Bad: nested where with length comparison
void checkMatrix(List<List<int>> matrix) {
  if (matrix.where((row) => row.isNotEmpty).length == matrix.length) {
    print('All rows are non-empty');
  }
}

// Bad: where with complex predicate and length check
void checkAllPositive(List<int> numbers) {
  final allPositive = numbers.where((n) => n > 0 && n < 100).length == numbers.length;
}

// Bad: filtered emptiness in a variable declaration.
void verifyList(List<String> items) {
  bool allEmpty = items.where((i) => i.isNotEmpty).isEmpty;
}

// Regression: the violation must still be found inside Dart 3 containers
// (pattern declaration, labeled statement, switch expression and subject,
// collection if/spread, record field).
void containersRegression(int rcount, List<int> items) {
  final (ra, _) = (items.where((x) => x > 1).isEmpty, 0);
  lbl: {
    final rb = items.where((x) => x > 1).isEmpty;
    print(rb);
  }
  final rc = switch (rcount) {
    0 => items.where((x) => x > 1).isEmpty,
    _ => null,
  };
  final rd = switch (items.where((x) => x > 1).isEmpty) {
    _ => 0,
  };
  final re = [if (rcount > 0) items.where((x) => x > 1).isEmpty];
  final rf = [...[items.where((x) => x > 1).isEmpty]];
  final rg = (p: items.where((x) => x > 1).isEmpty, q: 0);
  print([ra, rc, rd, re, rf, rg]);
}

bool parenthesized(List<int> items) =>
    (items.where((x) => x > 0).isEmpty);

void universalComparisons(List<int> items) {
  final equalsTrue = items.where((x) => x > 0).isEmpty == true;
  final differsFalse = items.where((x) => x > 0).isEmpty != false;
  final reversedTrue = true == items.where((x) => x > 0).isEmpty;
  final reversedFalse = false != (items.where((x) => x > 0).isEmpty);
  final negatedComparison = !(items.where((x) => x > 0).isEmpty == false);
  final repeatedComparison = (items.where((x) => x > 0).isEmpty == false) == false;
  final doubleNegation = !(!items.where((x) => x > 0).isEmpty);
}

class CollectionOwner {
  final List<int> items = [];
  final List<int> others = [];

  bool allPositive() =>
      this.items.where((x) => x > 0).length == this.items.length;

  bool unrelated() =>
      this.items.where((x) => x > 0).length == this.others.length;
}

bool noEmptySet(Set<String> values) =>
    values.where((value) => value.isEmpty).isEmpty;

bool noEvenIterable(Iterable<int> values) =>
    values.where((value) => value.isEven).isEmpty;

bool noneMatch(List<int> values, bool Function(int) predicate) =>
    values.where(predicate).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
2void validateItems(List<int> items) {
3 if (items.where((x) => x > 0).isEmpty) {
Use `every(predicate)` instead of comparing the filtered and original iterable lengths.
9void checkAllValid(List<String> values) {
10 bool allNonEmpty = values.where((v) => v.isNotEmpty).length == values.length;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
18 final data = [2, 4, 6, 8];
19 final allOdd = data.where((n) => n % 2 == 0).isEmpty;
Use `every(predicate)` instead of comparing the filtered and original iterable lengths.
23void checkMatrix(List<List<int>> matrix) {
24 if (matrix.where((row) => row.isNotEmpty).length == matrix.length) {
Use `every(predicate)` instead of comparing the filtered and original iterable lengths.
30void checkAllPositive(List<int> numbers) {
31 final allPositive = numbers.where((n) => n > 0 && n < 100).length == numbers.length;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
35void verifyList(List<String> items) {
36 bool allEmpty = items.where((i) => i.isNotEmpty).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
42void containersRegression(int rcount, List<int> items) {
43 final (ra, _) = (items.where((x) => x > 1).isEmpty, 0);
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
44 lbl: {
45 final rb = items.where((x) => x > 1).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
48 final rc = switch (rcount) {
49 0 => items.where((x) => x > 1).isEmpty,
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
51 };
52 final rd = switch (items.where((x) => x > 1).isEmpty) {
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
54 };
55 final re = [if (rcount > 0) items.where((x) => x > 1).isEmpty];
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
55 final re = [if (rcount > 0) items.where((x) => x > 1).isEmpty];
56 final rf = [...[items.where((x) => x > 1).isEmpty]];
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
56 final rf = [...[items.where((x) => x > 1).isEmpty]];
57 final rg = (p: items.where((x) => x > 1).isEmpty, q: 0);
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
61bool parenthesized(List<int> items) =>
62 (items.where((x) => x > 0).isEmpty);
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
64void universalComparisons(List<int> items) {
65 final equalsTrue = items.where((x) => x > 0).isEmpty == true;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
65 final equalsTrue = items.where((x) => x > 0).isEmpty == true;
66 final differsFalse = items.where((x) => x > 0).isEmpty != false;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
66 final differsFalse = items.where((x) => x > 0).isEmpty != false;
67 final reversedTrue = true == items.where((x) => x > 0).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
67 final reversedTrue = true == items.where((x) => x > 0).isEmpty;
68 final reversedFalse = false != (items.where((x) => x > 0).isEmpty);
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
68 final reversedFalse = false != (items.where((x) => x > 0).isEmpty);
69 final negatedComparison = !(items.where((x) => x > 0).isEmpty == false);
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
69 final negatedComparison = !(items.where((x) => x > 0).isEmpty == false);
70 final repeatedComparison = (items.where((x) => x > 0).isEmpty == false) == false;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
70 final repeatedComparison = (items.where((x) => x > 0).isEmpty == false) == false;
71 final doubleNegation = !(!items.where((x) => x > 0).isEmpty);
Use `every(predicate)` instead of comparing the filtered and original iterable lengths.
78 bool allPositive() =>
79 this.items.where((x) => x > 0).length == this.items.length;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
85bool noEmptySet(Set<String> values) =>
86 values.where((value) => value.isEmpty).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
88bool noEvenIterable(Iterable<int> values) =>
89 values.where((value) => value.isEven).isEmpty;
Use `every((element) => !predicate(element))` instead of `where(predicate).isEmpty`.
91bool noneMatch(List<int> values, bool Function(int) predicate) =>
92 values.where(predicate).isEmpty;

Valid

example.dartdart
// Good: using .every() for a universal predicate.
void validateItems(List<int> items) {
  if (items.every((x) => x > 0)) {
    print('All items are positive');
  }
}

// Good: .every() pattern for checking all elements
void checkAllValid(List<String> values) {
  bool allNonEmpty = values.every((v) => v.isNotEmpty);
  if (allNonEmpty) {
    print('All strings are non-empty');
  }
}

// Good: assignment with .every()
void processCollection() {
  final data = [2, 4, 6, 8];
  final allEven = data.every((n) => n % 2 == 0);
}

// Good: nested every() instead of where().length
void checkMatrix(List<List<int>> matrix) {
  if (matrix.every((row) => row.isNotEmpty)) {
    print('All rows are non-empty');
  }
}

// Good: other iterable methods are fine
void useOtherMethods(List<int> numbers) {
  final filtered = numbers.where((n) => n > 0).toList();
  final hasAny = numbers.any((n) => n > 10);
}

// Negated filtered emptiness is any(predicate), not every(predicate).
void existentialChecks(List<int> items) {
  final hasPositive = !items.where((x) => x > 0).isEmpty;
  final parenthesized = !(items.where((x) => x > 0).isEmpty);
  final nested = !((items.where((x) => x > 0).isEmpty));
  final comparedFalse = items.where((x) => x > 0).isEmpty == false;
  final comparedTrue = items.where((x) => x > 0).isEmpty != true;
  final reversedFalse = false == (items.where((x) => x > 0).isEmpty);
  final reversedTrue = true != ((items.where((x) => x > 0).isEmpty));
  final negatedComparison = !(items.where((x) => x > 0).isEmpty == true);
  final repeatedComparison = (items.where((x) => x > 0).isEmpty == false) != false;
  final allNonPositive = items.every((x) => !(x > 0));
  final empty = <int>[].every((x) => !(x > 0));
  print([hasPositive, parenthesized, nested, allNonPositive, empty]);
}

class FakeString {
  String where(bool Function(int) predicate) => '';
}

class FakeMap {
  Map<int, int> where(bool Function(int) predicate) => {};
}

void unrelatedReceivers(
  List<int> xs,
  List<int> ys,
  List<int> Function() source,
  FakeString text,
  FakeMap map,
) {
  final textEmpty = text.where((x) => x > 0).isEmpty;
  final mapEmpty = map.where((x) => x > 0).isEmpty;
  final textLength = text.where((x) => x > 0).length == xs.length;
  final mapLength = map.where((x) => x > 0).length == xs.length;
  final unrelated = xs.where((x) => x > 0).length == ys.length;
  final repeatedCall = source().where((x) => x > 0).length == source().length;
}

void nullableChains(List<int>? items, List<int> values) {
  final nullableFilter = items?.where((x) => x > 0).isEmpty;
  final nullableEmpty = values.where((x) => x > 0)?.isEmpty;
  final nullableLength =
      values.where((x) => x > 0)?.length == values.length;
  final nullableOriginal =
      values.where((x) => x > 0).length == values?.length;
}

bool unresolved(dynamic values) => values.where((value) => true).isEmpty;

class Lookalike {
  Lookalike where(bool Function(int) predicate) => this;
  bool get isEmpty => true;
}

bool lookalike(Lookalike values) => values.where((value) => true).isEmpty;

Configure prefer-iterable-every

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "complexity": {
        "prefer-iterable-every": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/complexity/prefer-iterable-every: <reason>
  • prefer-moving-to-variableprefer-moving-to-variable

    Flags repeated property/getter chains in local variable initializers.

  • prefer-null-aware-operatorsprefer_null_aware_operatorsrecommended

    Flags x == null ? null : x.y (and the inverted x != null ? x.y : null).

  • unnecessary-constunnecessary_constrecommended

    Flags a redundant const keyword inside an already-const context.

  • unnecessary-getters-settersunnecessary_getters_settersrecommended

    Flags a trivial getter/setter pair that only reads and writes a private field.

  • unnecessary-lambdasunnecessary_lambdasrecommended

    Flags a closure that only forwards its parameters to a function a tear-off could name.

  • unnecessary-overridesunnecessary_overridesrecommended

    Flags a member that does nothing but forward to super with the same arguments and resolved contract.

  • widget-tree-depthflutter

    Limits the depth of an inline Flutter widget construction tree.

  • avoid-classes-with-only-static-membersavoid_classes_with_only_static_members

    Flags a class that declares only static members.