C# 构建一个RX操作符,将键值对中的一个可观测值拆分为多个可观测值,每个不同的键一个

C# 构建一个RX操作符,将键值对中的一个可观测值拆分为多个可观测值,每个不同的键一个,c#,system.reactive,reactive-programming,C#,System.reactive,Reactive Programming,我是一个RX新手,试图构建一些对我来说似乎很复杂的东西 问题是:我有一个热的可观察对象,它正在生成键值对。他们没有特别的顺序。输出应该是源可观察项中每个不同键的可观察项。因此,对于源中的每个值,结果应该是:如果键还没有被看到,则新的可观察值将立即产生相应的值。如果之前已经看到过键,那么相应的值应该由已经存在的相应可观察对象生成。因此: <1, foo>-<2, foo>-<2, foo>-<1, foo>-<3, foo>-<4,

我是一个RX新手,试图构建一些对我来说似乎很复杂的东西

问题是:我有一个热的可观察对象,它正在生成键值对。他们没有特别的顺序。输出应该是源可观察项中每个不同键的可观察项。因此,对于源中的每个值,结果应该是:如果键还没有被看到,则新的可观察值将立即产生相应的值。如果之前已经看到过键,那么相应的值应该由已经存在的相应可观察对象生成。因此:

<1, foo>-<2, foo>-<2, foo>-<1, foo>-<3, foo>-<4, foo>-<1, foo>-<3, foo>x

Output:
<1, foo>-------------------<1, foo>-------------------<1, foo>---------x
---------<2, foo>-<2,foo>----------------------------------------------x
------------------------------------<3, foo>-------------------<3, foo>x
---------------------------------------------<4, foo>------------------x
我正试图用window实现这一点,但我一直在研究如何检测一个键已经被看到,然后将该值路由到现有的可观察值

谢谢

GroupBy就是这么做的。e、 g:

var subject = new Subject<KeyValuePair<int, string>>();

var groups = subject.GroupBy(x => x.Key);
我们得到:

1
2
这是产生的两个流的关键。如果我们使用SelectMany将GroupBy的结果展平,并仅提取出值,则有两种方法可以证明我们拥有所有值:

groups.SelectMany(x => x).Subscribe(y => Console.WriteLine(y.Value));

subject.OnNext(new KeyValuePair<int, string>(1, "a"));
subject.OnNext(new KeyValuePair<int, string>(2, "b"));
subject.OnNext(new KeyValuePair<int, string>(1, "c"));

正如预期的那样。

请注意,GroupBy组持续到源流终止-因此,如果您有很长的运行流,您可能需要GroupByUntil,它可以根据持续时间选择器限制每个组的生存期。如果组已被持续时间选择器终止,则带有该键的新值将导致形成一个新组。是的,这正是我需要的。我希望我没有糟糕地、缓慢地重新实现太多其他现有的操作符=/谢谢你的解释!
groups.SelectMany(x => x).Subscribe(y => Console.WriteLine(y.Value));

subject.OnNext(new KeyValuePair<int, string>(1, "a"));
subject.OnNext(new KeyValuePair<int, string>(2, "b"));
subject.OnNext(new KeyValuePair<int, string>(1, "c"));
a
b
c