How to emit 1's not closely followed by a 2

Viewed 72

I have an observable stream which emits numbers, I want another stream that emits all 1's that are not closely followed by a 2 (within say 200ms), so for example from this source stream:

(every character is 100ms)

1...12...112...11121...

The result should be:

..1.......1.....11...1.

How would I do that using rxjs@^6.6.7?

2 Answers

Based on @martin's answer:

when a 1 is emitted,

  • we create a new observable that waits for the next element for 200ms
  • if no element comes within the 200msec, we emit the 1 and close the subscription
  • if an element comes and it's a 2, we emit nothing and close the subscription
  • if an element comes and it's a 1, we emit the original value and close the subscription

https://stackblitz.com/edit/rxjs-ihyznt?devtoolsheight=66&file=index.ts

source
  .pipe(
    filter(value => value != 2),
    mergeMap(value =>
      source.pipe(
        first(),
        filter(v => v != 2),
        map(_ => value),
        timeout(200),
        catchError(_ => of(value))
      )
    )
  )
  .subscribe(value => console.log(value));

I would do it like this. Each 1 is wrapped with an inner Observable and delayed by 200ms which might be completed earlier using takeUntil() and thus ignored:

source$
  .pipe(
    filter(value => value === 1),
    mergeMap(value => of(value).pipe(
      delay(200),
      takeUntil(source$.pipe(
        filter(value => value === 2),
      )),
    )),
  )
Related