合并可观察量

时间:2013-11-20 20:24:05

标签: system.reactive reactive-programming

这里我们有一个Observable Sequence ...在.NET中使用Rx。

var aSource = new Subject<int>();

var bSource = new Subject<int>();

var paired = Observable
            .Merge(aSource, bSource)
    .GroupBy(i => i).SelectMany(g => g.Buffer(2).Take(1));

paired.Subscribe(g => Console.WriteLine("{0}:{1}", g.ElementAt(0), g.ElementAt(1)));

aSource.OnNext(4);
bSource.OnNext(1);
aSource.OnNext(2);
bSource.OnNext(5);
aSource.OnNext(3);
bSource.OnNext(3);
aSource.OnNext(5);
bSource.OnNext(2);
aSource.OnNext(1);
bSource.OnNext(4);

输出: 3:3 5:5 2:2 1:1 4:4

每当一对数字以相同的ID到达时,我们就会收到事件。

完美!正是我想要的。

两组,按价值配对。

下一个问题......

如何为值序列获取selectmany / buffer。

所以1,2,3,4,5通过OnNext()到达aSource和bSource。然后激活ConsoleWriteLine()1-5。然后当2,3,4,5,6到达时,我们得到另一个console.writeline()。有人提出任何线索吗?

Rx论坛立即建议查看.Window()

http://introtorx.com/Content/v1.0.10621.0/17_SequencesOfCoincidence.html

表面看起来很完美。在我的情况下,我需要一个值为4的窗口,在这种情况下。

查询序列中的哪个属于获得此效果?

var paired = Observable.Merge(aSource,bSource).GroupBy(i =&gt; i).SelectMany(g =&gt; g.Buffer(2).Take(1));

输出 1,2,3,4,5:1,2,3,4,5 2,3,4,5,6:2,3,4,5,6

此致

丹尼尔

2 个答案:

答案 0 :(得分:1)

假设事件随机到达来源,请使用"Reordering events with Reactive Extensions"的答案按顺序获取事件。

然后使用Observable.Buffer创建一个滑动缓冲区:

// get this using the OrderedCollect/Sort in the referenced question
IObservable<int> orderedSource;

// then subscribe to this
orderedSource.Buffer(5, 1);

答案 1 :(得分:0)

这是一个扩展方法,当它有n个相同id的输入时触发。

public static class RxExtension
    {

        public static IObservable<TSource> MergeBuffer<TSource>(this IObservable<TSource> source, Func<TSource, int> keySelector, Func<IList<TSource>,TSource> mergeFunction, int bufferCount)
        {
            return Observable.Create<TSource>(o =>  {
                var buffer = new Dictionary<int, IList<TSource>>();
                return source.Subscribe<TSource>(i =>
                {
                    var index = keySelector(i);
                    if (buffer.ContainsKey(index))
                    {
                        buffer[index].Add(i);
                    }
                    else 
                    {
                        buffer.Add(index, new List<TSource>(){i});
                    }
                    if (buffer.Count==bufferCount)
                    {
                        o.OnNext(mergeFunction(buffer[index]));
                        buffer.Remove(index);
                    }
                });
            });
        }
    }

致电分机。

mainInput = Observable.Merge(inputNodes.ToArray()).MergeBuffer<NodeData>(x => x.id, x => MergeData(x), 1);