Iterables and Functional Collection Operations
Iterable operations are lazy until you consume them (toList, forEach, length, a for loop). List is an Iterable with indexed access.
final nums = [5, 3, 8, 1, 9, 2];
nums.map((n) => n * 2); // lazy Iterable
nums.where((n) => n.isEven).toList(); // filter
nums.fold<int>(0, (sum, n) => sum + n); // reduce with an initial value
nums.reduce((a, b) => a > b ? a : b); // max (throws on empty)
nums.any((n) => n > 8); nums.every((n) => n > 0);
nums.firstWhere((n) => n > 4, orElse: () => -1);
nums.lastWhere((n) => n < 5);
nums.singleWhere((n) => n == 8);
nums.take(3); nums.skip(2); nums.takeWhile((n) => n > 2); nums.skipWhile((n) => n > 2);
[[1, 2], [3]].expand((l) => l); // flatMap
nums.followedBy([10, 11]);
nums.whereType<int>();
nums.toSet(); nums.toList(growable: false);
nums.asMap(); // {0: 5, 1: 3, ...}
nums.indexed; // Iterable<(int, int)> records (Dart 3)
for (final (i, n) in nums.indexed) print('$i: $n');
// Chaining
final result = nums.where((n) => n > 2).map((n) => n * n).toList()..sort();
// Lazy evaluation
final lazy = Iterable.generate(1000000, (i) => i).where((i) => i % 7 == 0).take(3);
print(lazy.toList()); // computes only what's needed
// package:collection extensions
import 'package
…10.1 Custom Iterables
class Countdown extends Iterable<int> {
final int start;
Countdown(this.start);
@override
Iterator<int> get iterator => _CountdownIterator(start);
}
class _CountdownIterator implements Iterator<int> {
int _current;
_CountdownIterator(int start) : _current = start + 1;
@override
int get current => _current;
@override
bool moveNext() => --_current > 0;
}
for (final n in Countdown(3)) print(n); // 3 2 1
Countdown(5).map((n) => n * 10).toList();