Is it possible to create a ReactiveUI derived collection that has more elements in it than the original?
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);
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!
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);
Edit: Alright, here we go:
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).
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.
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.
Hmm...I'm not all that familiar with ReactiveUI, but just reading thru, it looks like you need to alter where your SelectMany
goes:
var jam = cars.SelectMany(x => x.Passengers).CreateDerivedCollection(p => p);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With