Skip to content
AgileLogics
6 min read

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
  • map transforms every element; where keeps 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.
  • firstWhere returns the first match (and throws if there's none — pass orElse: 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 map or where result 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]