I have three (or more) observable sequences of bool
:
IObservable<bool> a0 = ...;
IObservable<bool> a1 = ...;
IObservable<bool> a2 = ...;
These sequences generate mostly false
values but once in a while there is a true
(the sequences can also be empty). I'm not interested in the values themselves but rather in the order of the true
values. So if a0
is true
, then a2
is true and finally a1
, I'd like to perform some action:
(a0, a2, a1) => ...do something...
But if the true
values appear in another order, I'd like to do something else:
(a2, a1, a0) => ...do something else...
(a0, a1, a2) => ...do something entirely else...
So I'm only interested in the first true
value of each sequence and depending on the order in which they occur, I'd like to perform some action.
I could record the timestamp of each first occurrence of true
and then sort in a CombineLatest
call, but I have a feeling there is a better way. One problem with this approach is that I am now dependent on granularity of recorded timestamps.
Firstly, you only need the true values so ignore the rest. Second, you can encode each observable into a more semantic meaning (perhaps a string?). Third, you can then merge these streams, wait for 3 values to arrive, and act based on them.
Set up:
var a0 = new Subject<bool>();
var a1 = new Subject<bool>();
var a2 = new Subject<bool>();
Encoding:
var a0t = a0.Where(x => x).Select(x => "a0").Take(1); // thanks Matthew Finlay
var a1t = a1.Where(x => x).Select(x => "a1").Take(1);
var a2t = a2.Where(x => x).Select(x => "a2").Take(1);
Merge and get after three values:
var merged = a0t.Merge(a1t).Merge(a2t);
var message = merged.Buffer(3).Subscribe(x => ProcessMessage(String.Join("", x)));
The processing section:
public void ProcessMessage(string message)
{
switch(message) {
case "a0a1a2": Console.WriteLine("1"); break;
case "a1a2a0": Console.WriteLine("2"); break;
case "a2a1a0": Console.WriteLine("3"); break;
}
}
And test:
a1.OnNext(true);
a2.OnNext(true);
a0.OnNext(true);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.