2017-08-25 1 views
0

Utilisation RxSwift, que j'ai une classe A qui contient une observable de nombre entiercartographie plat propriétés observables d'une collection observable dans RxSwift

class A: { 
    let count: Observable<Int> 
} 

et une collection observable d'objets d'un

let data: Observable<[A]> 

Je veux définir un sum: Observable<Int> qui sera la somme de tous les count sur tous les objets dans data. Chaque fois que les modifications observables data ou l'une des modifications de la propriété count, le sum doit également changer.

Comment y parvenir? J'ai essayé quelques combinaisons flapMap et map mais seulement obtenu une solution quand sum obtient mis à jour seulement quand data obtient mis à jour, en ignorant les changements count.

Répondre

0
let sum = data.flatMap { Observable.from($0).flatMap { $0.count }.reduce(0, accumulator: +) } 

'.reduce() émet seulement à la fin, de sorte qu'il doit être à l'intérieur de l'extérieur '.flatMap()'

Update 1:

 let sumSubject: BehaviorSubject<Observable<Int>> = BehaviorSubject.create(Observable.empty()) 
     let sum = sumSubject.switchLatest() 
     // every time it has to be a new 'data' observable! 
     sumSubject.onNext(data.flatMap { Observable.from($0).flatMap { $0.count }.reduce(0, accumulator: +) }) 

Mise à jour 2:

let counts: Observable<[Int]> = data.flatMap { Observable.combineLatest($0.map { $0.count }) } 
    let sum: Observable<Int> = counts.map { $0.reduce(0) { $0 + $1 } } 
+0

Cela ne fait qu'émettre 0 pour moi. La version avant edit a émis la valeur correcte firt time, mais n'en a pas émis une nouvelle quand un 'count' a été mis à jour. –

+0

Essayez d'ajouter '.debug()' après chaque opérateur pour déterminer où en amont de chaque opérateur se termine. Fondamentalement, '.reduce()' n'émet qu'à la fin de l'amont, alors que '.scan()' sur chaque élément amont. Si tout le reste échoue, essayez '.switchLatest()' sur un 'BehaviourSubject >' que vous allez nourrir avec du nouveau 'Observable.just ([A(), A(), ...])' –

+0

Le problème avec scan (dans la version avant edit) c'est qu'il va continuer à ajouter les chiffres quand quelque chose change, sans compter à nouveau. Comme quand un compte passe de 1 à 2, le résultat ne sera pas 2 mais 3 (1 + 2). –