Sturm
Sturm

Reputation: 4125

Subscribe on bool state using Rx

I have an IObservable<bool> and I want to be notified when the last n items are set to true.

For that I'm trying things like:

MyBool.Buffer(10).SelectMany(x => x).All(x => x).Subscribe(x => /*do something*/);

But it only fires once; it seems like the OnCompleted is fired somehow.

Upvotes: 1

Views: 405

Answers (1)

Enigmativity
Enigmativity

Reputation: 117175

You are effectively buffering and flattening your observable. Calling .Buffer(10).SelectMany(x => x) is like a non-operation as it emits what ever went in.

What you need to do is more like this:

    MyBool
        .Buffer(10, 1)
        .Select(xs => xs.All(x => x))
        .Where(x => x);

I assumed you wanted to know whenever there are 10 trues in a row, so that if there are 11 you are notified twice.


The reason behind Buffer(10, 1) is the way Buffer works - this gives a buffer of 10 elements and moves along by 1. If I did Buffer(10) I would get 10 elements and move along by ten.

If I did Observable.Range(0, 5).Buffer(3) I get {0, 1, 2}, {3, 4}, but if I did Observable.Range(0, 5).Buffer(3, 1) I get {0, 1, 2}, {1, 2, 3}, {2, 3, 4}, {3, 4}, {4}.

If you want to know when a false comes thru after the trues then try this:

MyBool
        .Buffer(3, 1)
        .Select(xs => xs.All(x => x))
        .Buffer(2, 1)
        .Where(x => x[0] || x[1]);

This gives these possible combinations:

results

Upvotes: 3

Related Questions