J'essaie de filtrer une liste avec RxJava2 de telle sorte que chaque élément (objet) de la liste doit passer un contrôle de validation et que je reçois une liste résultante avec uniquement les éléments qui réussissent ce test. Par exemple, si mon objet avait la structure suivante,
class MyClassA {
int value1;
int value2;
}
Je souhaite uniquement obtenir la liste des éléments pour lesquels le value2
est 10.
J'ai une fonction d'appel d'API qui renvoie un observable de liste, c'est-à-dire Observable<List<MyClassA>>
comme suit,
apiService.getListObservable()
.subscribeOn(Schedulers.io)
.observeOn(AndroidSchedulers.mainThread());
et j'aimerais que la sortie soit filtrée. J'ai donc essayé d'ajouter un opérateur .filter()
à ce qui précède, mais il semble nécessiter un Predicate<List<MyClassA>>
plutôt qu'un objet MyClassA
avec lequel je peux vérifier et autoriser uniquement ceux où value2 == 10
.
Je suis assez nouveau sur RxJava et RxJava2 et il semble que je manque quelque chose de fondamental ici?
TIA
Vous pouvez dérouler la liste puis rassembler les entrées qui ont passé le filtre:
apiService.getListObservable()
.subscribeOn(Schedulers.io)
.flatMapIterable(new Function<List<MyClassA>, List<MyClassA>>() {
@Override public List<MyClassA> apply(List<MyClassA> v) {
return v;
}
})
.filter(new Predicate<MyClassA>() {
@Override public boolean test(MyClassA v) {
return v.value2 == 10;
}
})
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...);
Vous pouvez jeter un oeil à ce qui suit. Il montre comment imprimer uniquement les objets filtrés OR les listes contenant des objets filtrés. Ici, la logique de filtrage consiste à conserver les org.Apache.commons.lang3.Tuple.Pair
s qui ont des nombres pairs à droite.
public static void main(String[] args) {
// print raw output
getListObservable().subscribe(System.out::println);
// print the objects post filtering
getListObservable().flatMap(v -> Observable.from(v)).filter(p -> p.getRight()%2==0).subscribe(System.out::println);
// print the list refined with only filtered objects
getListObservable().flatMap(v -> Observable.just(v.stream().filter(p -> p.getRight()%2==0).collect(Collectors.toList()))).subscribe(System.out::println);
}
private static Observable<List<Pair<Integer, Integer>>> getListObservable() {
return Observable.create(subscriber -> {
for(int i=0; i<5; i++){
List<Pair<Integer, Integer>> list = new ArrayList<>();
for(int j=0; j<5; j++){
list.add(Pair.of(i, j));
}
subscriber.onNext(list);
}
});
}
Sortie avec contenu de observable:
[(0,0), (0,1), (0,2), (0,3), (0,4)]
[(1,0), (1,1), (1,2), (1,3), (1,4)]
[(2,0), (2,1), (2,2), (2,3), (2,4)]
[(3,0), (3,1), (3,2), (3,3), (3,4)]
[(4,0), (4,1), (4,2), (4,3), (4,4)]
La sortie ne doit contenir que des objets filtrés:
(0,0)
(0,2)
(0,4)
(1,0)
(1,2)
(1,4)
(2,0)
(2,2)
(2,4)
(3,0)
(3,2)
(3,4)
(4,0)
(4,2)
(4,4)
La sortie doit contenir les listes qui ne contiennent que des objets filtrés.
[(0,0), (0,2), (0,4)]
[(1,0), (1,2), (1,4)]
[(2,0), (2,2), (2,4)]
[(3,0), (3,2), (3,4)]
[(4,0), (4,2), (4,4)]