创建一个元素比原始元素更多的 ReactiveUI 派生集合 [英] Creating a ReactiveUI derived collection with more elements than the original
问题描述
是否可以创建一个包含比原始元素更多的 ReactiveUI 派生集合?
Is it possible to create a ReactiveUI derived collection that has more elements in it than the original?
我已经看到有一种过滤集合和选择单个属性的方法,但我正在寻找的是等效于可枚举的 SelectMany 操作.
I've seen that there is a way of filtering a collection, and selecting single properties, but what I'm looking for is the equivalent of the SelectMany operation for enumerables.
举个例子,想象一下试图获得一个派生集合,代表每一个陷入交通拥堵的乘客.
To illustrate, imagine trying to get a derived collection representing every passenger stuck in a traffic jam.
class Car
{
ReactiveCollection<Passenger> Passengers;
}
var TrafficJam=new ReactiveCollection<Car>();
EveryPassengerInTheTrafficJam=Cars.CreateDerivedCollection(c=>c.Passengers);
以上不起作用,我认为错误是 IEnumerable
can't be cast to ReactiveCollection
- 或者其他什么在任何情况下,都要处理类型.
The above doesn't work, I think the error was IEnumerable<ReactiveCollection<Passenger>>
can't be cast to ReactiveCollection<Passenger>
- or something up with the types, in any case.
我无法找出这种扁平化的正确方法 - 诚然,我在这里可能完全错误的树,所以请告诉我是否有更好的方法来实现同样的目标!
I can't figure out the right approach for this flattening - admittedly I may be barking up completely the wrong tree here, so please let me know if there's a better way of achieving the same thing!
推荐答案
目前,CreateDerivedCollection
不支持 SelectMany
作为转换,这太棘手了手柄移除.如果你没有很多项目,你可以每次都重新生成集合:
At the moment, CreateDerivedCollection
doesn't support SelectMany
as a transformation, it gets too Tricky to handle removes. If you don't have many items, you can just regenerate the collection every time:
cars.Changed
.Select(_ => cars.SelectMany(x => x.Passengers).ToList())
.ToProperty(this, x => x.Passengers);
好的,我们开始:
var whenCarsOrPassengersInThoseCarsChange = Observable.Merge(
cars.Changed
.SelectMany(_ =>
cars.Select(x => x.Passengers.Changed).Merge())
.Select(_ => Unit.Default),
cars.Changed.Select(_ => Unit.Default));
whenCarsOrPassengersInThoseCarsChange.StartWith(Unit.Default)
.Select(_ => cars.SelectMany(x => x.Passengers).ToList())
.ToProperty(this, x => x.Passengers);
因此,我们的想法是,当我们想要重新评估乘客列表时,有两种主要情况:
So, the idea is that we've got two main situations when we want to reevaluate the passengers list:
- 当其中一名乘客换车时
- 当其中一辆车发生变化时
然而,棘手的部分是,我们只想观察集合中汽车的乘客(即,如果汽车被移除,我们不再关心它的乘客).
However, the tricky part is, we only want to watch passengers for cars in the collection (i.e. if a car is removed, we no longer care about its passengers).
所以,那个奇怪的 SelectMany 中的想法是,每次汽车列表发生变化时,构建一个新的 Observable 列表来表示乘客集合何时发生变化,并将它们合并在一起".
So, the idea in that weird SelectMany is, "Every time the car list changes, build a new list of Observables that represent when the passenger collection changes, and merge them all together".
但是,如果我们只有有那个声明,我们将不得不等待添加一辆车并且它的乘客改变,然后我们才能获得新的乘客名单,所以当汽车列表也发生变化时,我们也必须更新.
However, if we only had that statement, we would have to wait for a car to be added and its passengers change before we got a new passenger list, so we also have to update when the list of cars change too.
在这种情况下,我实际上并不关心这些 Observable 输出的值,只是当它们发生时.Unit"是 void 的 Rx 版本,它只有一个值,Unit.Default".当你只关心事情发生的时候,你会使用它,而不是它的价值是什么.
In this case, I actually don't care about the values that these Observables put out, just when they happen. "Unit" is the Rx version of void, it only has a single value, "Unit.Default". You use it when you only care when something happens, not what the value of it is.
这篇关于创建一个元素比原始元素更多的 ReactiveUI 派生集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!