๐ŸŽ“ A1Learner
๐Ÿ”
0 of 24 lessons completed

Dart Stream Transformations

A stream transformation builds a new stream from an existing stream. Each transformation filters, changes, or trims the values as they pass through.

Filtering and changing values

The where call keeps the even numbers 2 and 4. The map call then multiplies each kept number by ten.

import 'dart:async';

Future<void> main() async {
  var stream = Stream.fromIterable([1, 2, 3, 4]);
  await for (var n in stream.where((n) => n.isEven).map((n) => n * 10)) {
    print(n);
  }
}

Removing consecutive duplicates

The list repeats 1 and 2 in a row but returns to 1 later. Only the repeats that sit next to an equal value are dropped.

import 'dart:async';

Future<void> main() async {
  var stream = Stream.fromIterable([1, 1, 2, 2, 3, 1]);
  await for (var n in stream.distinct()) {
    print(n);
  }
}

Trimming with skip and take

The skip call drops the first value 10. The take call then lets two values through and ends the stream.

import 'dart:async';

Future<void> main() async {
  var stream = Stream.fromIterable([10, 20, 30, 40]);
  await for (var n in stream.skip(1).take(2)) {
    print(n);
  }
}

Mapping with asyncMap

The tag function returns a future for each number. The values still arrive in the order of the source stream, as 3 then 1 then 2.

import 'dart:async';

Future<String> tag(int n) async => 'tag$n';

Future<void> main() async {
  var stream = Stream.fromIterable([3, 1, 2]).asyncMap(tag);
  await for (var t in stream) {
    print(t);
  }
}

Example

import 'dart:async';

Future<void> main() async {
  var stream = Stream.fromIterable([8, 3, 12, 5, 20]);
  await for (var n in stream.where((n) => n >= 8).map((n) => n + 2)) {
    print(n);
  }
}

Key points

  • A transformation takes a stream and returns a new stream.
  • The where method keeps only the values that pass its test.
  • The map method changes each kept value into a new value.
  • The distinct method drops a value only when it matches the value just before it.
  • The skip method drops a set number of opening values.
  • The take method ends the stream after a set number of values.
  • The asyncMap method maps each value with a function that returns a future, and it emits the results in source order.

In this example, where keeps 8, 12, and 20 because each one is at least 8. The map call adds 2 to each kept value. The loop prints 10, 14, and 22 in that order.

Note

Transformations chain in order, so each method in a chain receives the values the earlier methods passed on.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท DartPad

Exercise

A stream holds 2, 2, 3, 2 in that order. What does distinct print, value by value?