web-dev-qa-db-fra.com

Liste de filtres RxJava2 <Object>

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

7
Bootstrapper

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(...);
22
akarnokd

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.Pairs 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)]
0
Pavan Kumar