我做过一些关于反应性linq的研究,也称为Rx.NET。我已经看到SelectMany方法的行为如下结果:展平observable中的内容,使其从多个流转到单个流。我的问题是,是否有一种方法在完全相反的方向上起作用?这意味着在将多个事件流放入一个可观察对象(multiplexing)之后,如何实现这一点?我知道GroupBy与我要求的行为非常相似,只是缺少一件事:我想要一个可能尚未发出的密钥的可观察性。
我正在考虑自己实施这种行为,但如果有机会,我错过了这种方法的存在,请告诉我,我错了,它确实存在!
答案 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();
这仍然给我奇数,但我现在可以创建偶数数字,而无需开始新的分组。