Collection Methods: map, where, and fold
Prerequisites: Anonymous functions and closures
Dart collections have methods that take functions and replace most hand-written loops.
map and where
void main() {
final prices = [10.0, 20.0, 30.0];
print(prices.map((p) => p * 1.2));
print(prices.map((p) => p * 1.2).toList());
final nums = [for (var i = 1; i <= 10; i++) i];
print(nums.where((n) => n.isEven).toList());
print(nums.firstWhere((n) => n > 4));
}
(12.0, 24.0, 36.0)
[12.0, 24.0, 36.0]
[2, 4, 6, 8, 10]
5
maptransforms every element;wherekeeps matching elements.- Both return a lazy
Iterable, printed in parentheses. The work happens only when the result is used; call.toList()to get a list. firstWherereturns the first match (and throws if there's none — passorElse:for a fallback).
fold and reduce — combine into one value
void main() {
final nums = [1, 2, 3, 4];
print(nums.fold<int>(0, (sum, n) => sum + n));
print(nums.reduce((a, b) => a * b));
print(['a', 'b', 'c'].fold<String>('', (acc, s) => acc + s.toUpperCase()));
}
10
24
ABC
fold starts from a value you give; reduce starts from the first
element (and throws on an empty list).
fold<int> states the result type explicitly. Dart usually infers it
from the surrounding code (for example, final total = nums.fold(0, ...)
works), but inside print(...) — which accepts any object — it can't,
and the compiler reports The operator '+' isn't defined for the type 'Object?'.
Other everyday methods
void main() {
final words = ['apple', 'avocado', 'banana', 'cherry'];
print(words.any((w) => w.startsWith('c')));
print(words.every((w) => w.length > 3));
print(words.take(2).toList());
print(words.skip(2).toList());
print(words.join(' | '));
print(words.map((w) => w.length).reduce((a, b) => a > b ? a : b));
}
true
true
[apple, avocado]
[banana, cherry]
apple | avocado | banana | cherry
7
Chaining
void main() {
final orders = [120.0, 45.0, 300.0, 80.0];
final bigOrdersTotal = orders
.where((o) => o > 100)
.map((o) => o * 0.9)
.fold(0.0, (sum, o) => sum + o);
print(bigOrdersTotal);
}
378.0
Common mistakes
- Printing a
maporwhereresult and seeing(1, 2, 3)instead of a list — add.toList(). - Relying on a lazy iterable being evaluated. If the function has side effects, nothing happens until the iterable is used.
Practice
Given ['ada', 'linus', 'grace', 'al'], produce a list of the names
longer than 2 letters, with the first letter capitalized.
Show solution
void main() {
final names = ['ada', 'linus', 'grace', 'al'];
final result = names
.where((n) => n.length > 2)
.map((n) => n[0].toUpperCase() + n.substring(1))
.toList();
print(result);
}
[Ada, Linus, Grace]