如何将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"))
答案 0 :(得分: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
是否结束。我认为确实如此,但我没有测试过它。
答案 1 :(得分: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();
答案 2 :(得分:0)
我不太了解可观察物,但你能做到:
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();
当然,这种方法效率不高,特别是如果您知道日志语句按顺序排列。