繁体   English   中英

Rx.net中SelectMany的反向结果

[英]Reverse result from SelectMany in Rx.net

我已经完成了一些有关反应式linq(也称为Rx.NET)的研究。 我已经看到,SelectMany方法的行为最终产生了以下结果:将可观察内容的内容展平,从而使它从许多流变为单个流。 我的问题是,是否有一种方法的作用恰恰相反? 意思是在将多个事件流放在一个可观察的( 多路复用 )中之后,将如何实现呢? 我知道GroupBy的行为与我要求的行为非常相似,只是缺少一件事:我希望对一个可能尚未发出的密钥进行观察。

我当时正在考虑自己执行行为,但是如果有机会,我会错过这种方法的存在,请告诉我我错了,而且实际上存在!

GroupBy是您想要的,但是正如您所指出的,它确实不足以预先创建“已知”组。 但是,我想您可以发挥创造力,并为每个已知组的值播种序列,如下所示:

如果来源是这样的

Observable.Interval(TimeSpan.FromMilliseconds(100))
    .GroupBy(i => i % 4)

您可以将其修改为类似

var seed = new[] { 0L, 1L, 2L, 3L }.ToObservable();
Observable.Concat(seed, Observable.Interval(TimeSpan.FromMilliseconds(100)))
    .GroupBy(i => i % 4)
    .Select(grp=>grp.Skip(1))   //Ignore the first/seed value.

您对GroupBy是正确的。 可以很容易地将其设置为提前预订任何密钥。 只要这样做:

IObservable<int> oddNumbers =
    Observable
        .Range(0, 10)
        .GroupBy(x => x % 2)
        .Where(gx => gx.Key == 1)
        .Merge();

如果我订阅,我将获得:

1 
3 
5 
7 
9

但是,这有点浪费时间,因为这直接等同于:

IObservable<int> oddNumbers =
    Observable
        .Range(0, 10)
        .Where(x => x % 2 == 1);

我看到它可能有用的唯一方法是:

IConnectableObservable<IGroupedObservable<int, int>> groupedNumbers =
    Observable
        .Range(0, 10)
        .GroupBy(x => x % 2)
        .Publish();

Func<IConnectableObservable<IGroupedObservable<int, int>>, int, IObservable<int>> anyProject =
    (source, key) =>
        source
            .Where(gx => gx.Key == key)
            .Merge();

IObservable<int> oddNumbers = anyProject(groupedNumbers, 1);

oddNumbers.Subscribe(x => Console.WriteLine(x));

groupedNumbers.Connect();

那仍然给了我奇数,但是我现在可以创建可观察的偶数而无需开始新的分组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM