runLengthEncode method

  1. @useResult
List<(T, int)> runLengthEncode()

Run-length encodes this iterable into (value, count) pairs.

Example:

[1, 1, 2, 2, 2].runLengthEncode(); // [(1, 2), (2, 3)]

Audited: 2026-06-12 11:26 EDT

Implementation

@useResult
List<(T, int)> runLengthEncode() {
  final List<(T, int)> result = <(T, int)>[];
  // Use a `hasPrev` flag, NOT `prev == null`, as the "no previous run"
  // sentinel: when T is nullable, a real `null` element would otherwise be
  // mistaken for "no run yet", dropping/miscounting a run of nulls and
  // breaking the round-trip with runLengthDecode.
  bool hasPrev = false;
  late T prev;
  int count = 0;
  for (final T element in this) {
    if (!hasPrev || element != prev) {
      if (hasPrev) result.add((prev, count));
      prev = element;
      count = 1;
      hasPrev = true;
    } else {
      count++;
    }
  }
  if (hasPrev) result.add((prev, count));
  return result;
}