2

次の 3 つ (またはそれ以上) の観測可能なシーケンスがありboolます。

IObservable<bool> a0 = ...;
IObservable<bool> a1 = ...;
IObservable<bool> a2 = ...;

これらのシーケンスはほとんどの値を生成しますが、たまにfalse値が生成されますtrue(シーケンスは空になることもあります)。値自体には興味がありませんが、値の順序に興味がありtrueます。したがって、がa0trueであり、最終的に が である場合、何らかのアクションを実行したいと思います。truea2a1

(a0, a2, a1) => ...do something...

しかし、true値が別の順序で表示される場合は、別のことをしたいと思います。

(a2, a1, a0) => ...do something else...
(a0, a1, a2) => ...do something entirely else...

したがって、各シーケンスの最初の値のみに関心がtrueあり、それらが発生する順序に応じて、何らかのアクションを実行したいと考えています。

が最初に発生するたびにタイムスタンプを記録してからtrue、呼び出しを並べ替えることができCombineLatestますが、もっと良い方法があると感じています。このアプローチの問題点の 1 つは、記録されたタイムスタンプの粒度に依存するようになったことです。

4

1 に答える 1

4

まず、必要なのは真の値だけなので、残りは無視してください。次に、各オブザーバブルをよりセマンティックな意味(おそらく文字列?)にエンコードできます。次に、これらのストリームをマージし、3つの値が到着するのを待って、それらに基づいて動作することができます。

設定:

var a0 = new Subject<bool>();
var a1 = new Subject<bool>();
var a2 = new Subject<bool>();

エンコーディング:

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);

マージして、次の3つの値を取得します。

var merged = a0t.Merge(a1t).Merge(a2t);
var message = merged.Buffer(3).Subscribe(x => ProcessMessage(String.Join("", x)));

処理セクション:

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;
    }
}

そしてテスト:

a1.OnNext(true);
a2.OnNext(true);
a0.OnNext(true);
于 2012-04-23T13:02:54.993 に答える