如何将慢速移动的可观察量与快速移动的可观察量的最新值组合

时间:2014-01-07 19:51:59

标签: c# system.reactive

一位朋友问我这个问题 - 我认为这是一个很好的问题所以我在这里重新发布它和我的答案:

我有这两个流:

var slowSource = Observable.Interval(TimeSpan.FromSeconds(1));
var fastSource = Observable.Interval(TimeSpan.FromMilliseconds(100));

我希望将它们组合在一起,以便生成包含的输出对 - slowSource的下一个值 - 来自fastSource的最新值

我只需要来自slowSource的每个值一个输出对。例如,前三个输出值可能如下所示:

0,8
1,18,
2,28

一个连接让我接近,但我最终得到每个slowSource多个输出(由于持续时间重叠的方式,我猜):

var qry = slowSource.Join(
          right: fastSource,
          leftDurationSelector: i => fastSource,
          rightDurationSelector: j => fastSource,
          resultSelector: (l, r) => {return new {L = l, R = r};})

.Subscribe(Console.WriteLine);

使用GroupJoin和Select生成看起来正确的输出:

var qry2 = slowSource.GroupJoin(
              right: fastSource,
              leftDurationSelector: i => fastSource,
              rightDurationSelector: j => fastSource,
              resultSelector: (l, r) => {return new {L= l, R = r};}
              )
          .Select(async item => {
            return new {L = item.L, R = await item.R.FirstAsync()};})
          .Subscribe(Console.WriteLine);

然而,这并不是一种很好的方法;必须有一种更好的方法,使用其他组合器以更简单的方式做这样的事情。有吗?

2 个答案:

答案 0 :(得分:3)

Zip的重载如何将IObservableIEnumerable结合起来。它使用MostRecent()来获取流的最新值的样本作为可枚举。

slowSource.Zip(fastSource.MostRecent(0), (l,r) => new {l,r})

答案 1 :(得分:1)

Observable.CombineLatest http://msdn.microsoft.com/en-us/library/hh211991(v=vs.103).aspx可以提供帮助,然后您需要以slowSource的速率重新采样fastSource。

var combinedObservable = slowSource.CombineLatest
    ( fastSource.Sample(slowSource)
    , (s,f)=>new {s,f}
    );