Последовательность реализации: List‹Observable‹T›› -› Observable‹List‹T››

Для каждого типа T, имеющего список n Observables of Ts, я хотел бы построить Observable, испускающий список n Ts каждый раз, когда один из исходных Observables что-то испускает. В функциональной литературе его часто называют оператором «последовательности».

Пример желаемого поведения в псевдосинтаксисе:

val o1 = BehaviourSubject.create(true)
val o2 = BehaviourSubject.create(false)
val listOfObservables = [o1,o2]

val observableOfList = sequence(listOfObservables)

observableOfList.subscribe(print)

o2.onNext(true)

// Expected output:
// [true, false]
// [true, true]

Я написал следующую наивную реализацию в java, которая плохо себя ведет:

public static <T> Observable<List<T>> sequence(List<Observable<T>> from) {
  return fold(from, Observable.<List<T>>never().startWith(new ArrayList<T>()),
            (arrayListObservable, observable) -> {
    return Observable.combineLatest(arrayListObservable, observable, (ts, t) -> {
      ts.add(t);
      return ts;
    });
  });
}

public static <F, T> T fold(final Iterable<? extends F> elements, final T zero, final Func2<T, F, T> f) {
  T currentValue = zero;
  for (final F element : elements) {
    currentValue = f.call(currentValue, element);
  }
  return currentValue;
}

// Actual output
// [true, false]
// [true, false, true]

Каким-то образом мне нужно перестроить полученный список вместо добавления новых значений к существующему. Как бы вы, ребята / дамы, поступили с этим?

Спасибо за ваше время и будущие ответы!


person Alexandre Mazari    schedule 15.05.2014    source источник


Ответы (1)


Rxx имеет перегруженную версию CombineLatest, которая принимает набор наблюдаемых и делает именно то, что вам нужно. Вы должны иметь возможность довольно легко перенести исходный код этого метода на Java.

person Brandon    schedule 15.05.2014
comment
Привет, Брэндон, спасибо за ваш ответ, который заставил меня глубоко пересмотреть документ rxjava. И знаешь, что? В последних версиях 0.18.x есть функция CombineLatest! Вот как я использовал его для получения последовательности :: List‹Observable‹T›› -› -› Observable‹List‹T›› эквивалент: - person Alexandre Mazari; 17.05.2014