将一个可观察量与另一个可观察量的最新值相结合
本文关键字:观察 另一个 最新 相结合 一个 | 更新日期: 2023-09-27 18:34:25
我正在尝试组合两个值共享某个键的可观察量。
每当第一个可观察量产生新值时,我想生成一个新值,并结合第二个可观察量的最新值,该选择取决于第一个可观察量的最新值。
伪代码示例:
var obs1 = Observable.Interval(TimeSpan.FromSeconds(1)).Select(x => Tuple.create(SomeKeyThatVaries, x)
var obs2 = Observable.Interval(TimeSpan.FromMilliSeconds(1)).Select(x => Tuple.create(SomeKeyThatVaries, x)
from x in obs1
let latestFromObs2WhereKeyMatches = …
select Tuple.create(x, latestFromObs2WhereKeyMatches)
有什么建议吗?
显然,这可以通过订阅第二个可观察量并创建一个字典来实现,该字典具有可由键索引的最新值。但我正在寻找一种不同的方法..
使用场景:根据股票报价流计算的一分钟价格柱线。在这种情况下,键是股票代码,字典包含混凝土股票代码的最新要价和买入价,然后在计算中使用。
(顺便说一下,谢谢戴夫和詹姆斯,这是一次非常富有成效的讨论)
(对格式感到抱歉,很难在iPad上正确获得。
...您为什么要寻找不同的方法?听起来你对我来说是正确的。这是简短,简单的代码...粗略地说,它将是这样的:
var cache = new ConcurrentDictionary<long, long>();
obs2.Subscribe(x => cache[x.Item1] = x.Item2);
var results = obs1.Select(x => new {
obs1 = x.Item2,
cache.ContainsKey(x.Item1) ? cache[x.Item1] : 0
});
归根结底,C# 是一种面向对象的语言,线程安全可变集合的繁重工作已经为您完成。
可能有花哨的 Rx 方法(感觉可能涉及连接)......但它的可维护性如何?它将如何表现?
$0.02
我想知道这种查询的目的。您介意描述一下使用场景吗?
不过,似乎以下查询可能会解决您的问题。如果你已经有某种方法来识别每个值的起源,那么最初的预测就没有必要了,但为了概括起见,我把它们包括在内,以与你极其抽象的提问模式保持一致。;-)
注意:我假设someKeyThatVaries
不是您显示的共享数据,这就是为什么我还包含术语anotherKeyThatVaries
;否则,整个查询对我来说真的没有意义。
var obs1 = Observable.Interval(TimeSpan.FromSeconds(1))
.Select(x => Tuple.Create(someKeyThatVaries, x));
var obs2 = Observable.Interval(TimeSpan.FromSeconds(.25))
.Select(x => Tuple.Create(anotherKeyThatVaries, x));
var results = obs1.Select(t => new { Key = t.Item1, Value = t.Item2, Kind = 1 })
.Merge(
obs2.Select(t => new { Key = t.Item1, Value = t.Item2, Kind = 2 }))
.GroupBy(t => t.Key, t => new { t.Value, t.Kind })
.SelectMany(g =>
g.Scan(
new { X = -1L, Y = -1L, Yield = false },
(acc, cur) => cur.Kind == 1
? new { X = cur.Value, Y = acc.Y, Yield = true }
: new { X = acc.X, Y = cur.Value, Yield = false })
.Where(s => s.Yield)
.Select(s => Tuple.Create(s.X, s.Y)));