scan
function stable
Useful for encapsulating and managing state. Applies an accumulator (or "reducer function") to each value from the source after an initial state is established -- either via a seed value (second argument), or from the first value from the source.
scan<V, A, S>(accumulator: (acc: V | A | S, value: V, index: number) => A, seed?: S): OperatorFunction<V, V | A>
Parameters
| accumulator | A "reducer function". This will be called for each value after an initial state is acquired. |
| seed | Optional. Default is The initial state. If this is not provided, the first value from the source will be used as the initial state, and emitted without going through the accumulator. All subsequent values will be processed by the accumulator function. If this is provided, all values will go through the accumulator function. |
Returns
OperatorFunction<V, V | A>: A function that returns an Observable of the accumulated values.
Description
It's like reduce, but emits the current accumulation state after each update
This operator maintains an internal state and emits it after processing each value as follows:
- First value arrives
- If a
seedvalue was supplied (as the second argument toscan), letstate = seedandvalue = firstValue. - If NO
seedvalue was supplied (no second argument), letstate = firstValueand go to 3.
- Let
state = accumulator(state, value).
- If an error is thrown by
accumulator, notify the consumer of an error. The process ends.
- Emit
state. - Next value arrives, let
value = nextValue, go to 2.
Example
An average of previous numbers. This example shows how not providing a seed can prime the stream with the first value from the source.
import { interval, of } from 'rxjs';
import { scan, map } from 'rxjs/operators';
const numbers$ = of(1, 2, 3);
numbers$
.pipe(
// Get the sum of the numbers coming in.
scan((total, n) => total + n),
// Get the average by dividing the sum by the total number
// received so var (which is 1 more than the zero-based index).
map((sum, index) => sum / (index + 1))
)
.subscribe(console.log); Example
The Fibonacci sequence. This example shows how you can use a seed to prime accumulation process. Also... you know... Fibinacci. So important to like, computers and stuff that its whiteboarded in job interviews. Now you can show them the Rx version! (Please don't, haha)
import { interval } from 'rxjs';
import { scan, map, startWith } from 'rxjs/operators';
const firstTwoFibs = [0, 1];
// An endless stream of Fibonnaci numbers.
const fibonnaci$ = interval(1000).pipe(
// Scan to get the fibonnaci numbers (after 0, 1)
scan(([a, b]) => [b, a + b], firstTwoFibs),
// Get the second number in the tuple, it's the one you calculated
map(([, n]) => n),
// Start with our first two digits :)
startWith(...firstTwoFibs)
);
fibonnaci$.subscribe(console.log); Overloads
scan(accumulator: (acc: V | A, value: V, index: number) => A): OperatorFunction<V, V | A>
Parameters
| accumulator | Type: |
Returns
OperatorFunction<V, V | A>
scan(accumulator: (acc: A, value: V, index: number) => A, seed: A): OperatorFunction<V, A>
Parameters
| accumulator | Type: |
| seed | Type: |
Returns
OperatorFunction<V, A>
scan(accumulator: (acc: A | S, value: V, index: number) => A, seed: S): OperatorFunction<V, A>
Parameters
| accumulator | Type: |
| seed | Type: |
Returns
OperatorFunction<V, A>
See Also
© 2015–2021 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors.
Code licensed under an Apache-2.0 License. Documentation licensed under CC BY 4.0.
https://rxjs.dev/api/operators/scan