map, where и take в Dart
Слушателю не всегда нужны сырые значения из
источника. Оператор map принимает
функцию от элемента и возвращает поток, где
каждая ячейка уже заменена результатом этой
функции.
Строки можно привести к длине, не меняя исходный генератор:
import 'dart:async';
Stream<String> words() async* {
yield 'cat';
yield 'river';
}
void main() async {
Stream<int> lens = words().map((String text) {
return text.length;
});
await for (int len in lens) {
print(len);
}
}
В консоли 3 и 6 - порядок
сохраняется, меняется только вид данных на
выходе map.
Не каждое значение нужно дальше по цепочке.
where оставляет элемент только если
предикат истинен:
import 'dart:async';
Stream<int> nums = Stream.fromIterable([1, 2, 3, 4]);
void main() async {
Stream<int> evens = nums.where((int n) {
return n % 2 == 0;
});
await for (int even in evens) {
print(even);
}
}
Печатаются 2 и 4. Нечетные номера
отброшены до приема, порядок оставшихся не
нарушен.
Источник может быть длиннее, чем нужно сейчас.
take обрезает поток после N принятых
значений. Операторы удобно читать сверху вниз:
import 'dart:async';
Stream<int> nums = Stream.fromIterable([1, 2, 3]);
void main() async {
Stream<int> part = nums
.map((int n) {
return n * 2;
})
.where((int n) {
return n > 2;
})
.take(2);
await for (int n in part) {
print(n);
}
}
На выходе 4 и 6. Четвертое и
пятое значения до цикла не доходят, если их
нет в исходной тройке после отбора.
Поток из строк "go" и "up"
пропустите через map в верхний
регистр. Прочитайте и выведите обе строки.
Из чисел 5, 10, 15
оставьте те, что больше 8, через
where. Выведите отобранные значения.
Из потока букв "w", "x",
"y", "z" возьмите первые
две через take и выведите их.