1

想象一个导航应用程序,它绘制用户的当前位置和一条折线(显示您开车去哪里的东西)到目标目的地。这意味着应该有两个事件流,一个用于位置更新,一个用于基于位置更新新计算的折线。

问题是绘制折线的计算成本很高,所以我只想在用户从计算它的最后一个点移动一定距离后才这样做。

这是它应该如何工作的:

  1. 红色 - 用户移动一小段距离,没有任何反应
  2. 蓝色 - 用户移出绿色圆圈,这是计算方向时与原始点的距离,因此计算出新的方向并设置了新的橙色半径

导航

我在这里遇到的问题是我不知道如何进行下一次计算。我想这需要某种折叠,但我不确定如何在 Rx 中表达它。

它应该看起来像这样(其中的两个参数表示某种元组)。

locationUpdates.Where((previous, current) => IsFarEnough(previous, current))
               .SomethingThatPutsCurrentBackIntoTheCondition()
4

1 回答 1

4

Observable.Scan 是折叠或比较当前和以前项目的最简单方法。我在这里写了一些漂亮的图表。这是那篇文章的代码:

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));
}

并对其进行单元测试:

public class PairWithPreviousTests : ReactiveTest
{
    [Test]
    public void Works()
    {
        var testScheduler = new TestScheduler();

        var source = Observable.Range(1, 3);

        var results = testScheduler.Start(
            () => source.PairWithPrevious());

        results.Messages.AssertEqual(
            OnNext(Subscribed, Tuple.Create(0, 1)),
            OnNext(Subscribed, Tuple.Create(1, 2)),
            OnNext(Subscribed, Tuple.Create(2, 3)),
            OnCompleted<Tuple<int, int>>(Subscribed));
    }
}

你应该能够破解这个,看看如何使用 Scan 来推进你需要的东西。

于 2013-10-26T15:38:48.697 回答