Создание производной коллекции ReactiveUI с большим количеством элементов, чем исходная

Возможно ли создать производную коллекцию ReactiveUI, в которой есть больше элементов, чем оригинал?

Я видел, что есть способ фильтрации коллекции и выбора отдельных свойств, но то, что я ищу, эквивалентно операции SelectMany для перечислений.

Чтобы проиллюстрировать, представьте себе попытку получить производную коллекцию, представляющую каждого пассажира, застрявшего в пробке.

class Car 
{
    ReactiveCollection<Passenger> Passengers;
}

var TrafficJam=new ReactiveCollection<Car>();
EveryPassengerInTheTrafficJam=Cars.CreateDerivedCollection(c=>c.Passengers);

Вышеупомянутое не работает, я думаю, что ошибка была IEnumerable<ReactiveCollection<Passenger>> не может быть добавлена ​​в ReactiveCollection<Passenger> - или что-то вроде типов в любом случае.

Я не могу понять правильный подход для этого сплющивания - по общему признанию, я, возможно, полностью лаял совершенно неправильное дерево здесь, поэтому, пожалуйста, дайте мне знать, есть ли лучший способ добиться того же самого!

Ответ 1

В настоящий момент CreateDerivedCollection не поддерживает SelectMany как преобразование, оно слишком сложно обрабатывать удалением. Если у вас нет большого количества предметов, вы можете просто обновлять коллекцию каждый раз:

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);

Итак, идея состоит в том, что у нас есть две основные ситуации, когда мы хотим переоценить список пассажиров:

  • Когда один из пассажиров меняет автомобиль
  • Когда один из автомобилей меняет

Однако сложной частью является то, что мы хотим только наблюдать за пассажирами для автомобилей в коллекции (т.е. если автомобиль снят, мы больше не заботимся о его пассажирах).

Правильное отслеживание суицидальных пассажиров

Итак, идея в этом странном SelectMany заключается в следующем: "Каждый раз, когда список автомобилей изменяется, создайте новый список Observables, который будет отображаться, когда меняется коллекция пассажиров, и объедините их все вместе".

Однако, если бы у нас было только это выражение, нам пришлось бы ждать, пока автомобиль будет добавлен, и его пассажиры изменятся, прежде чем мы получим новый список пассажиров, поэтому нам также нужно обновить, когда список автомобилей изменится.

Что это за "Unit"?

В этом случае на самом деле меня не волнуют ценности, которые вызывают эти Observables, только когда они происходят. "Единица" - это Rx-версия void, она имеет только одно значение "Unit.Default". Вы используете его, когда вам все равно, когда что-то происходит, а не то, что его значение.

Ответ 2

Хм... Я не так хорошо знаком с ReactiveUI, но, просто прочитав, похоже, вам нужно изменить, куда идет ваш SelectMany:

var jam = cars.SelectMany(x => x.Passengers).CreateDerivedCollection(p => p);