识别具有最小和最大持续时间的元素序列

Recognize a sequence of elements with minimum and maximum duration

给定一个 IObservable<bool> 和两个 TimeSpan 阈值,minDurationmaxDuration,我需要转换序列以便:

为了让事情更清楚,假设 minDuration = 3maxDuration = 6,并假设物品以每秒一个的速度发射:

fffttffttfftttttttttttffftttffffttttf

------------------y--------x-------x-

我的猜测是我需要实现自定义运算符,但作为 RX 新手我不知道如何实现,而且我很难找到超出使用扩展方法组合现有运算符的示例.

欢迎提供有关实现自定义运算符的教程和示例的链接。

如果我理解正确:

  1. 当您获得大于 minDuration 但小于 maxDuration 的连续真值时,您想要发出 x.
  2. 当您获得超过 maxDuration 的连续真值时,您想要发出 y.
  3. 在任何其他情况下,什么都不发射。

如果是这样,您的弹珠图应该看起来更像这样:

fffttffttfftttttttttttffftttffffttttf
           1234567       123    1234  (numbers for counting guidance)
-----------------y----------x-------x (mine)
------------------y--------x-------x- (yours)

这个x就只能假的出来了。你不能在 true 上发出它,因为你不知道未来的价值是多少!没有自定义运算符可以为您解决这个问题。

剩下的可以这样解决:

    var values = new List<bool> // matches fffttffttfftttttttttttffftttffffttttf
    {
        false,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        false,
        false,
        false,
        true,
        true,
        true,
        false,
        false,
        false,
        false,
        true,
        true,
        true,
        true,
        false,
    };

    var original = Observable.Interval(TimeSpan.FromSeconds(1))
        .Where(i => i < values.Count)
        .Select(i => values[(int)i]);
    TimeSpan minDuration = TimeSpan.FromSeconds(3);
    TimeSpan maxDuration = TimeSpan.FromSeconds(6);

    var trueWindows = original
        .TimeInterval()
        .Scan(TimeSpan.Zero, (a, t) => t.Value
            ? a + t.Interval
            : TimeSpan.Zero);
    var coupledWindows = trueWindows.Scan(new {Previous = TimeSpan.Zero, Current = TimeSpan.Zero},
        (o, t) => new {Previous = o.Current, Current = t})
        .Publish()
        .RefCount();
    var xS = coupledWindows.Where(o => o.Previous < maxDuration && o.Previous >= minDuration && o.Current == TimeSpan.Zero).Select(t => "X");
    var yS = coupledWindows.Where(o => o.Current >= maxDuration && o.Previous < maxDuration).Select(t => "Y");

至于教程,最好的资源是 http://introtorx.com/. Another somewhat good one is http://rxmarbles.com,尽管它使用非 .NET 函数名称。