Piotr Stapp
Piotr Stapp

Reputation: 19820

Map sequence in Rx.JS

I would like to map correct sequence using Rx.js. A simplest example will be using keyboard. I attach Rx.js to keyboard events and waiting for three A no matter what will be between them, except Q. When sequence is matched I would like to print OK on console. For example:

Should I use filter function and keep state inside it? Or there is an esier way to do that.

Upvotes: 3

Views: 64

Answers (2)

cartant
cartant

Reputation: 58410

You should be able to use the filter and scan operators to do what you want:

Rx.Observable.from("AsssAqweAbAAQAAA")

  // Only A and Q characters are important:

  .filter(char => (char === "A") || (char === "Q"))

  // Accumulate the A characters until there are three
  // or until a Q is received:

  .scan((acc, char) => {
    if ((char === "Q") || (acc.length === 3)) {
      acc = [];
    }
    if (char === "A") {
      acc.push(char);
    }    
    return acc;
  }, [])

  // Filter the accumulated characters until there
  // are three:

  .filter(acc => acc.length === 3)
  .mapTo("OK")
  .subscribe(value => console.log(value));
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>

Upvotes: 3

Olaf Horstmann
Olaf Horstmann

Reputation: 16892

You could try it with a bufferCount - though I'm not certain if your given examples are simplified and in reality a little more complex, but maybe this helps:

const source$ = Rx.Observable.from("aaqassaaassaaa");
source$.bufferCount(3, 1)
  // .do(console.log) // uncomment to see the processed data
  .filter(data => data.join("") === "aaa") // your detection-logic
  .mapTo("Ok")
  .subscribe(console.log);
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

Upvotes: 1

Related Questions