假设序列一正在web上检索站点1、2、3、4、5的内容(但将以不可预测的顺序返回(。
序列二将进入数据库以检索关于这些相同记录1、2、3、4、5的上下文(但就本示例而言,将以不可预测的顺序返回(。
当两个序列中的每个匹配对都准备好时,是否有一种Rx扩展方法可以将它们组合成一个序列?Ie,如果第一个序列以4,2,3,5,1的顺序返回,而第二个序列以1,4,3,2,5的顺序返回来,则一旦每对就绪,合并的序列将是(4,4(、(3,3(、(2,2(、(1,1(、(5,5(。我看过Merge和Zip,但它们似乎并不是我想要的。
我不想丢弃不匹配的配对,我认为这排除了简单的配对。哪里选择组合。
var paired = Observable
.Merge(aSource, bSource)
.GroupBy(i => i)
.SelectMany(g => g.Buffer(2).Take(1));
下面的测试给出了正确的结果。现在只需要int,如果你使用带有键和值的数据,那么你需要按i.键而不是i.进行分组
var aSource = new Subject<int>();
var bSource = new Subject<int>();
paired.Subscribe(g => Console.WriteLine("{0}:{1}", g.ElementAt(0), g.ElementAt(1)));
aSource.OnNext(4);
bSource.OnNext(1);
aSource.OnNext(2);
bSource.OnNext(4);
aSource.OnNext(3);
bSource.OnNext(3);
aSource.OnNext(5);
bSource.OnNext(2);
aSource.OnNext(1);
bSource.OnNext(5);
收益率:
4:4
3:3
2:2
1:1
5:5
编辑以回应Brandon:
对于项目是不同类别(A类别和B类别(的情况,可以进行以下调整。
using Pair = Tuple<AClass, BClass>;
var paired = Observable
.Merge(aSource.Select(a => new Pair(a, null)), bSource.Select(b => new Pair(null, b)))
.GroupBy(p => p.Item1 != null ? p.Item1.Key : p.Item2.Key)
.SelectMany(g => g.Buffer(2).Take(1))
.Select(g => new Pair(
g.ElementAt(0).Item1 ?? g.ElementAt(1).Item1,
g.ElementAt(0).Item2 ?? g.ElementAt(1).Item2));
那么您有两个要配对的可观察序列吗?
Rxx和GroupBy的配对可以在这里提供帮助。我认为类似于下面的代码可能会做你想要的
var pairs = stream1.Pair(stream2)
.GroupBy(pair => pair.Switch(source1 => source1.Key, source2 => source2.Key))
.SelectMany(group => group.Take(2).ToArray()) // each group will have at most 2 results (1 left and 1 right)
.Select(pair =>
{
T1 result1 = default(T1);
T2 result2 = default(T2);
foreach (var r in pair)
{
if (r.IsLeft) result1 = r.Left;
else result2 = r.Right;
}
return new { result1, result2 };
});
```
我还没有对它进行测试,也没有添加任何用于错误处理的内容,但我认为这正是您想要的。