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
seed
value was supplied (as the second argument toscan
), letstate = seed
andvalue = firstValue
. - If NO
seed
value was supplied (no second argument), letstate = firstValue
and 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