scanWith

fun <T, R> Flow<T>.scanWith(initialSupplier: suspend () -> R, operation: suspend (accumulator: R, value: T) -> R): Flow<R>(source)

Folds the given flow with operation, emitting every intermediate result, including the initial value supplied by initialSupplier at the collection time.

Note that the returned initial value should be immutable (or should not be mutated) as it is shared between different collectors.

This is a variant of scan that the initial value is lazily supplied, which is useful when the initial value is expensive to create or depends on a logic that should be executed at the collection time (lazy semantics).

For example:

flowOf(1, 2, 3)
.scanWith({ emptyList<Int>() }) { acc, value -> acc + value }
.toList()

will produce [[], [1], [1, 2], [1, 2, 3]].

Another example:

// Logic to calculate initial value (e.g. call API, read from DB, etc.)
suspend fun calculateInitialValue(): Int {
println("calculateInitialValue")
delay(1000)
return 0
}

flowOf(1, 2, 3).scanWith(::calculateInitialValue) { acc, value -> acc + value }

Parameters

initialSupplier

a function that returns the initial (seed) accumulator value for each individual collector.

operation

an accumulator function to be invoked on each item emitted by the current Flow, whose result will be emitted to collector via FlowCollector.emit and used in the next accumulator call.