得到的IObservable前一个元素,而无需重新评估顺序 [英] Get previous element in IObservable without re-evaluating the sequence

查看:144
本文介绍了得到的IObservable前一个元素,而无需重新评估顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的IObservable 序列(在无扩展为.NET),我想获得以前和当前元素的值,这样我可以比较它们。我在网上找到类似下面这完成任务的一个例子:

In an IObservable sequence (in Reactive Extensions for .NET), I'd like to get the value of the previous and current elements so that I can compare them. I found an example online similar to below which accomplishes the task:

sequence.Zip(sequence.Skip(1), (prev, cur) => new { Previous = prev, Current = cur })

它工作正常,除了它评估序列两次,我想避免的。你可以看到,它正在与此代码两次评估:

It works fine except that it evaluates the sequence twice, which I would like to avoid. You can see that it is being evaluated twice with this code:

var debugSequence = sequence.Do(item => Debug.WriteLine("Retrieved an element from sequence"));
debugSequence.Zip(debugSequence.Skip(1), (prev, cur) => new { Previous = prev, Current = cur }).Subscribe();



输出显示两倍的调试线路,因为有序列中的元素。

The output shows twice as many of the debug lines as there are elements in the sequence.

我明白为什么会这样,但到目前为止,我还没有发现,不计算两次序列的替代品。我怎么可以结合以前和当前只有一个序列的评价?

I understand why this happens, but so far I haven't found an alternative that doesn't evaluate the sequence twice. How can I combine the previous and current with only one sequence evaluation?

推荐答案

有对这个更好的解决方案,我认为,使用Observable.Scan和避免双重订阅:

There's a better solution to this I think, that uses Observable.Scan and avoids the double subscription:

public static IObservable<Tuple<TSource, TSource>>
    PairWithPrevious<TSource>(this IObservable<TSource> source)
{
    return source.Scan(
        Tuple.Create(default(TSource), default(TSource)),
        (acc, current) => Tuple.Create(acc.Item2, current));
}



我写这件事在我的博客在这里:的http://www.zerobugbuild.com/?p=213

进一步的修改,您可以使用任意类型的更清洁利用结果选择工作:

A further modification allows you to work with arbitrary types more cleanly by using a result selector:

public static IObservable<TResult> CombineWithPrevious<TSource,TResult>(
    this IObservable<TSource> source,
    Func<TSource, TSource, TResult> resultSelector)
{
    return source.Scan(
        Tuple.Create(default(TSource), default(TSource)),
        (previous, current) => Tuple.Create(previous.Item2, current))
        .Select(t => resultSelector(t.Item1, t.Item2));
}

这篇关于得到的IObservable前一个元素,而无需重新评估顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆