2012-04-23 13 views
2

の順序に基づいてboolの観察可能なシーケンスを、アクションを実行します空にすることもできます)。私は値自体に興味がなく、むしろtrueの値の順に興味があります。 a0trueであれば、その後、a2がtrueであり、最終的にはa1、私はいくつかのアクションを実行したいと思います:は、私は3つ(またはそれ以上)を持って観察可能なシーケンス内のイベント

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

しかしtrue値が別の順に表示された場合、私は他の何かをしたいと思います:

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

私は各シーケンスの最初のtrue値に興味があり、発生する順序によっては何らかのアクションを実行したいと考えています。

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

+0

は、彼らが真の任意の他の観察可能な火災の前に再び 'true'をを発射することはできますか?これは「ローリング」な試合ですか、それとも3つの試合がすべて合ったら一度に始まりますか? – yamen

+0

私は最初の「真の」価値にのみ関心があります。その後、私はオブザーバーを処分する。 –

+0

私はこれと他の素朴な前提に基づいて答えを出しました。しかし、全体的な方法は多くのシナリオに変換されるべきです。 – yamen

答えて

4

まず、真の値だけが必要なので、残りは無視してください。次に、各観測対象をより意味のある意味(おそらく文字列?)にエンコードすることができます。第3に、これらのストリームをマージし、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); 

マージしてもらう三つの値の後に:

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

ニース:)私は確かにこれを私の特定の状況に翻訳することができます。 –

+0

テスト済み:完全に動作します。ありがとう! –

+0

賢い答え、名声。 – BFree

関連する問題