![](/img/trans.png)
[英]How to combine a slow moving observable with the most recent value of a fast moving observable
[英]Combine overlapping observable streams but take most recent values
我已經嘗試過用Rx合並流的用例。 我有3個流輸出值:
S1: ----1----2----3----4----5-----6
S2: ----a---------c---------d------
S3: ---------x---------y----------z
我想合並(壓縮)流1和2以及1和3,邏輯是2和3永遠不能同時輸出值。
因此,所需的輸出為:
1,a
2,x
3,c
4,y
5,d
6,z
但是實際發生的是:
1,a
1,x
2,c
2,y
3,d
3,z
關於如何獲得所需輸出的任何線索?
碼:
Subject<int> s1 = new Subject<int>();
Subject<string> s2 = new Subject<string>();
Subject<string> s3 = new Subject<string>();
var zip1 = s1.Zip(s2, (x, y) => {
return new Tuple<int, string>(x, y);
});
var zip2 = s1.Zip(s3, (x, y) => {
return new Tuple<int, string>(x, y);
});
zip1.Subscribe(Console.WriteLine, () => Console.WriteLine("Completed"));
zip2.Subscribe(Console.WriteLine, () => Console.WriteLine("Completed"));
s1.OnNext(1);
s2.OnNext("a");
s1.OnNext(2);
s3.OnNext("x");
s1.OnNext(3);
s2.OnNext("c");
s1.OnNext(4);
s3.OnNext("y");
s1.OnNext(5);
s2.OnNext("d");
s1.OnNext(6);
s3.OnNext("z");
對於您擁有的每個流s2和s3,您可以創建一個Subject
,訂閱原始流,然后在等待下一個s1
值之后將該值傳遞給新的Subject
:
var zip1 = new Subject<Tuple<int, string>>();
s2.Subscribe(async value =>
{
var other = await s1.FirstAsync();
zip1.OnNext(Tuple.Create(other, value));
});
var zip2 = new Subject<Tuple<int, string>>();
s3.Subscribe(async value =>
{
var other = await s1.FirstAsync();
zip2.OnNext(Tuple.Create(other, value));
});
您已經聲明要管理流的時序,以便從s1
為合並的其他流的每個值產生一個值。 如果您確實做到這一點,那會沒事的。 如果從s1
產生的多個值在另一個流中沒有任何對應的值,則將被忽略,並且如果從其他流組合得到的多個值在s1
沒有對應的值,則將重復從s1
產生的下一個值。
還有一個更人為設計的選項,但是在值之間的時間安排上更加靈活。 這種方法是首先將每個流投影到具有該值但與其他流區分開的值中。 然后可以合並流,並用s1
壓縮,然后可以創建多個流,以過濾出每個特定流的值。 然后需要將這些投影回原始值。
var zip = s2.Select(s => Tuple.Create(1, s))
.Merge(s3.Select(s => Tuple.Create(2, s)))
.Zip(s1, Tuple.Create);
var zip1 = zip.Where(pair => pair.Item1.Item1 == 1)
.Select(pair => Tuple.Create(pair.Item2, pair.Item1.Item2));
var zip2 = zip.Where(pair => pair.Item1.Item1 == 2)
.Select(pair => Tuple.Create(pair.Item2, pair.Item1.Item2));
如果您實際上不需要單獨的流,而只想將輸出復制為單個流,則實際上要簡單得多:
var output = s1.Zip(s2.Merge(s3), Tuple.Create);
output.Subscribe(Console.WriteLine, () => Console.WriteLine("Completed"));
這不僅僅是這樣做的情況嗎?
var query =
s1.Zip(s2.Merge(s3),
(x, y) => new Tuple<int, string>(x, y));
鑒於問題中提供了您的代碼,我得到了這個結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.