4

如何将可观察Timestamped<T>的序列转换为TimeInterval<T>间隔是原始序列上时间戳之间的时间的序列?

给定输入序列..

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"))
4

3 回答 3

2

认为这可以做到。

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在任一序列结束时结束。我认为确实如此,但我还没有测试过。

于 2013-05-09T15:39:41.303 回答
1

也许你可以使用一个简单的投影结合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();
于 2013-05-09T16:15:37.137 回答
0

我对 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();

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

于 2013-05-09T15:40:34.370 回答