chunkWhile method

Iterable<List<E>> chunkWhile(
  1. bool predicate(
    1. E,
    2. E
    )
)

Splits this collection into a lazy Iterable of chunks, where chunks are created as long as predicate is true for a pair of entries.

For example, one-by-one increasing subsequences can be chunked as follows:

final list = [1, 2, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21];
final increasingSubSequences = list.chunkWhile((a, b) => a + 1 == b);

Here, increasingSubSequences would consist of [1, 2], [4], [9, 10, 11], [12], [15, 16] and finally [19, 20, 21].

See also:

  • splitWhen, which works similarly but with a reverted predicate.

Implementation

Iterable<List<E>> chunkWhile(bool Function(E, E) predicate) sync* {
  var currentChunk = <E>[];
  var hasPrevious = false;
  late E previous;

  for (final element in this) {
    if (!hasPrevious || predicate(previous, element)) {
      // keep element in current chunk
      currentChunk.add(element);
    } else {
      // start a new chunk containing the new element
      yield currentChunk;
      currentChunk = [element];
    }

    previous = element;
    hasPrevious = true;
  }

  if (currentChunk.isNotEmpty) yield currentChunk;
}