Rx.net中SelectMany的反向结果

时间:2016-02-11 20:29:25

标签: c# linq system.reactive

我做过一些关于反应性linq的研究,也称为Rx.NET。我已经看到SelectMany方法的行为如下结果:展平observable中的内容,使其从多个流转到单个流。我的问题是,是否有一种方法在完全相反的方向上起作用?这意味着在将多个事件流放入一个可观察对象(multiplexing)之后,如何实现这一点?我知道GroupBy与我要求的行为非常相似,只是缺少一件事:我想要一个可能尚未发出的密钥的可观察性。

我正在考虑自己实施这种行为,但如果有机会,我错过了这种方法的存在,请告诉我,我错了,它确实存在!

2 个答案:

答案 0 :(得分:3)

let startValue = arrow.transform let endValue = CATransform3DRotate( startValue, CGFloat(M_PI)/4.0, 0, 0, 1) // change the layer, without implicit animation // THIS IS WHAT YOU ARE ASKING ABOUT CATransaction.setDisableActions(true) arrow.transform = endValue // construct the explicit animation let anim = CABasicAnimation(keyPath:"transform") anim.duration = 0.8 anim.fromValue = NSValue(CATransform3D:startValue) anim.toValue = NSValue(CATransform3D:endValue) // ask for the explicit animation arrow.addAnimation(anim, forKey:nil) 正是您所寻找的,但正如您所指出的那样,它确实无法预先创建“已知”组。但是,我想你可以创造性地使用这些已知组中的每个组的值来生成序列:

如果来源是这样的

GroupBy

您可以将其修改为

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

答案 1 :(得分:2)

你是对的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();

这仍然给我奇数,但我现在可以创建偶数数字,而无需开始新的分组。