【问题标题】:Convert IObservable<Timestamped<T>> to IObservable<TimeInterval<T>>将 Observable<Time Stamped<T>> 转换为 Observable<Time Interval<T>>
【发布时间】:2013-05-10 00:15:37
【问题描述】:

如何将Timestamped&lt;T&gt; 的可观察序列转换为TimeInterval&lt;T&gt; 的序列,其中间隔是原始序列上时间戳之间的时间?

给定输入序列..

new Timestamped<int>(1, DateTime.Parse("2000-01-01 00:00:01"))
new Timestamped<int>(2, DateTime.Parse("2000-01-01 00:00:05"))
new Timestamped<int>(3, DateTime.Parse("2000-01-01 00:01:04"))

.. 输出将是:

new TimeInterval<int>(1, TimeSpan.Parse("00:00:00"))
new TimeInterval<int>(2, TimeSpan.Parse("00:00:04"))
new TimeInterval<int>(3, TimeSpan.Parse("00:00:59"))

【问题讨论】:

  • 是否要求第二个序列的条目数相同?这个隐式间隔需要什么行为? (另外,这种结构是不是你不能只打电话给originalSource.TimeInterval()?)
  • 时间戳和值来自日志文件,我希望能够重播它们(以各种速度),我想从序列开始获取相对时间并安排它们那样。序列应具有相同数量的元素。

标签: .net system.reactive


【解决方案1】:

认为就是这样。

var s = source.Publish().RefCount();
var sprev = s.Take(1).Concat(s);
var scurrent = s;

var converted = Observable.Zip(sprev, scurrent, (prev, current) =>
   new TimeInterval<int>(current.Value, current.Timestamp - prev.Timestamp));

我唯一不确定的是Zip 是否在任一序列结束时结束。我认为可以,但我没有测试过。

【讨论】:

    【解决方案2】:

    或许你可以使用简单的投影结合Do

    static IObservable<TimeInterval<T>> ToTimeInterval<T>(
        this IObservable<Timestamped<T>> source)
    {
        DateTimeOffset? previous = null;
        return source.Select(ts => 
            new
            {
                Timestamp = ts.Timestamp,
                Value = ts.Value,
                TimeSpan = previous.HasValue ? ts.Timestamp - previous
                                             : TimeSpan.FromSeconds(0)
            })
            .Do(xx => { previous = xx.Timestamp; })
            .Select(xx => new TimeInterval<T>(xx.Value, xx.TimeSpan));
    }
    

    像这样使用:

    var intervals = stampedData.ToTimeInterval();
    

    【讨论】:

      【解决方案3】:

      我不太了解 observables,但你能做到吗:

       myInputSequence.ToEnumerable().Select(t => 
          new TimeInterval<int>(
              t.Value,
              t.Value == 1 
                  ? new TimeSpan(0) 
                  : t.Timestamp - System.Reactive.Linq.Observable.ToEnumerable(myList).FirstOrDefault(t2 => t2.Value == t.Value - 1).Timestamp)
              ).ToObservable();
      

      当然这不是尽可能高效,尤其是如果您知道日志语句是按顺序排列的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-01
        • 2021-12-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-24
        • 1970-01-01
        相关资源
        最近更新 更多