Dart predicate
last modified October 18, 2026
In this article we show how to use predicates in Dart.
Predicate
Predicate in general meaning is a statement about something that is either true or false. In programming, predicates are single argument functions that return a boolean value.
Dart has no special predicate type; a predicate is simply a function of type
bool Function(T). Many collection methods accept predicates:
where, any, every,
firstWhere, removeWhere, retainWhere, and
others.
Dart Predicate example
The following is a simple predicate example.
bool isPositive(int e) {
return e > 0;
}
void main() {
final nums = <int>[0, -1, -2, -4, 5, 3, 6, -8];
final filtered = nums.where(isPositive);
print(filtered);
}
In the program, the isPositive predicate is used to select
positive values.
bool isPositive(int e) {
return e > 0;
}
The isPositive predicate returns true for all values that are
bigger than zero.
final filtered = nums.where(isPositive);
The predicate is passed to the where function, which returns all
elements that satisfy the predicate. We pass the function by its name (a
tear-off); the lambda (e) => isPositive(e) would work the same.
Note that where is lazy and returns an iterable, which is printed in
parentheses.
$ dart main.dart (5, 3, 6)
Dart anonymous predicate
The next example passes an anonymous predicate function to the
where function.
void main() {
final nums = <int>[0, -1, -2, -4, 5, 3, 6, -8];
final filtered = nums.where((e) => e < 0);
print(filtered);
}
It is often not necessary to give a function a name. We can just pass an anonymous function.
final filtered = nums.where((e) => e < 0);
With the help of the anonymous function, we select all negative values.
$ dart main.dart (-1, -2, -4, -8)
Dart predicate with any and every
The any function checks whether any element of the collection
satisfies the given predicate. The every function checks whether
all elements satisfy it.
void main() {
final nums = <int>[0, -1, -2, -4, 5, 3, 6, -8];
if (nums.any((e) => e > 0)) {
print('There is at least one positive value');
} else {
print('There are no positive values');
}
print(nums.every((e) => e > 0));
print(nums.every((e) => e.abs() < 10));
}
In the example, we find out if there are any positive values, and whether all values are positive or have an absolute value below 10.
$ dart main.dart There is at least one positive value false true
Dart predicate with firstWhere
The firstWhere function returns the first element that satisfies
the predicate. If there is none, it throws a StateError unless we
provide the orElse callback. The firstWhereOrNull
extension from the collection package returns null
instead.
void main() {
final words = ['sky', 'blue', 'cup', 'nice', 'top', 'cloud'];
print(words.firstWhere((e) => e.length > 3));
print(words.firstWhere((e) => e.length > 10, orElse: () => 'none'));
print(words.indexWhere((e) => e.startsWith('c')));
print(words.lastWhere((e) => e.length == 3));
}
The indexWhere function returns the index of the first matching
element, or -1. The lastWhere function searches from the end.
$ dart main.dart blue none 2 top
Dart predicate with removeWhere
The removeWhere function removes all elements from a collection
that satisfy the given predicate. The retainWhere function does the
opposite: it keeps only the elements that satisfy the predicate.
void main() {
final words = <String>['sky', 'blue', 'cup', 'nice', 'top', 'cloud'];
words.removeWhere((e) => e.length != 3);
print(words);
final nums = [1, 2, 3, 4, 5, 6];
nums.retainWhere((e) => e.isEven);
print(nums);
}
We have a list of strings. We remove all strings whose length is not 3. Then we
keep only the even numbers in a list of integers. Both methods modify the list
in place, so they do not work on lists created with const or
List.unmodifiable.
$ dart main.dart [sky, cup, top] [2, 4, 6]
Dart predicate multiple conditions
The next example uses a predicate with two conditions.
class Country {
final String name;
final int population;
Country(this.name, this.population);
@override
String toString() => '$name $population';
}
void main() {
final countries = <Country>[
Country('Iran', 80840713),
Country('Hungary', 9845000),
Country('Poland', 38485000),
Country('India', 1342512000),
Country('Latvia', 1978000),
Country('Vietnam', 95261000),
Country('Sweden', 9967000),
Country('Iceland', 337600),
Country('Israel', 8622000),
];
final filtered = countries
.where((e) => e.name.startsWith('I') && e.population > 10000000);
print(filtered);
}
We create a list of countries. We find all countries that start with 'I' and have a population over ten million.
countries
.where((e) => e.name.startsWith('I') && e.population > 10000000);
Two conditions are combined with the && operator inside one
anonymous predicate.
$ dart main.dart (Iran 80840713, India 1342512000)
Dart combining predicates
Because predicates are ordinary functions, we can write functions that create or
combine them. We define a Predicate type alias for readability.
typedef Predicate<T> = bool Function(T);
Predicate<T> not<T>(Predicate<T> p) => (e) => !p(e);
Predicate<T> and<T>(Predicate<T> a, Predicate<T> b) => (e) => a(e) && b(e);
Predicate<int> greaterThan(int n) => (e) => e > n;
void main() {
final nums = [3, 8, 12, 15, 20, 7, 30];
final isEven = (int e) => e.isEven;
print(nums.where(greaterThan(10)).toList());
print(nums.where(not(isEven)).toList());
print(nums.where(and(isEven, greaterThan(10))).toList());
}
The greaterThan function returns a predicate which remembers the
limit n (a closure). The not and and
functions build new predicates from existing ones.
$ dart main.dart [12, 15, 20, 30] [3, 15, 7] [12, 20, 30]
Source
In this article we have covered predicates in Dart.
Author
List all Dart tutorials.