RxJS - which operator can combine history of last N events?

Viewed 141

I'm looking for an operator which transform the stream to the stream with history or last N events.

So for a stream e.g. like this one:

clicks$.subscribe((ev) => ...)

I would like to have something like:

clicks$.pipe(
   historyOf(2)
).subscribe(([ev, ev-1, ev-2]) => ...)

Does the operator like this exists, or is there an easy way to combine existing operators to achieve the desired effect?

2 Answers

You can use ideally bufferCount or depending how you want to handle the beginning or termination of the sequence when there're less than N events also scan or filter:

const N = 3;

of(1, 2, 3, 4, 5, 6, 7).pipe(
  bufferCount(N, 1), // `1` means it'll emit after every emission from source
).subscribe(console.log);

... or if you want to skip emissions when the chain completes:

of(1, 2, 3, 4, 5, 6, 7).pipe(
  bufferCount(N, 1),
  filter(arr => arr.length === N),
).subscribe(console.log);

... or if you want the beginning events as well:

of(1, 2, 3, 4, 5, 6, 7).pipe(
  scan((acc, item) => [...acc, item].slice(-N), []),
).subscribe(console.log);

Live demo: https://stackblitz.com/edit/rxjs-xtnscq

I've started a (very) small library of some rxjs utils I've wanted. It happens to have one that may interest you: withHistory. From the docs:

source:         -1----2------3--------4--------5--------|
withHistory(2): -[1]--[2,1]--[3,2,1]--[4,3,2]--[5,4,3]--|
withHistory(0): -[1]--[2]----[3]------[4]------[5]------|

The library is here: https://github.com/simontonsoftware/s-rxjs-utils

Related