RXJS steam with distinct and throttleTime

Viewed 38

I need help to create a RXJS stream which does the following.

Input: Keyboard inputevent a to z Emit value if:

  • Character has NOT been used before
  • Character has been used before but it is more than 5 seconds ago. else discard value

Marble diagram (- is 1 second):

Input:  [aaa--b--b--aa--a-c-->
Output: [a----b-----a-----c-->
1 Answers

You can group your input by character using groupBy. We can then grab the first occurrence in each group and finally merge everything back. As luck would have it, groupBy lets us define a duration selector to specify how long a group should live, so if we set that to 5 seconds, we basically "reset" each group after that time:

const source$ = fromEvent(document, 'keydown').pipe(
  map((evt: KeyboardEvent) => evt.key)
);

source$.pipe(
  // create one group per character, with each
  // group living for only up to 5 seconds
  groupBy(key => key, undefined, () => timer(5000)),

  // From each group, only take the first element
  map(group$ => group$.pipe(first())),

  // put everything back together
  mergeAll()
)
Related