web-dev-qa-db-fra.com

Itérer la liste avec RxJava/RxAndroid

Je suis nouveau sur RxJava/RxAndroid mais je suis bloqué par mon cas d'utilisation.

J'essaie d'itérer un List<A> pour convertir chaque A en B de manière asynchrone (car il faut appeler la base de données) et ma Observer devrait être avertie de chaque conversion réussie (dans onNext()) afin d'effectuer certains travaux sur le thread principal. 

J'ai réussi à convertir la liste entière et j'ai ensuite reçu mon List<B> dans onNext() mais je dois être averti pour chaque élément, pas une fois que tous les éléments sont terminés.

J'ai essayé quelque chose avec l'opérateur from mais si j'utilise from(List<A>), ma Observer doit recevoir des objets du même type (A et non B).

Voici comment mon code pour convertir le List<A> entier en list<B> Que dois-je changer ici?

private List<A> listOfA;

private startConversion() {
    Observer observer = new Observer<List<B>>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
        }

        @Override
        public void onNext(List<B> convertedItems) {
            onConversionCompleted(convertedItems);
        }
    };

    Observable<B> observervable = Observable.fromCallable(new Callable<List<B>>() {
        @Override
        public List<B> call() throws Exception {
            return convertListOfAToListOfB(listOfA);
        }
    });

    subscription = observable
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
}

PS: c'est du pseudo-code.

Merci pour l'aide !

5
MHogge

Si vous souhaitez transformer chaque élément un par un dans un fil séparé, vous pouvez le faire de cette manière.

    Observable.from(list)    
            .map(input -> {
                // transform each A -> B
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(item -> {

            });

Si vous avez déjà observable quelle liste émet et que vous voulez la transformer en séquence, utilisez ceci:

        listObservable
            .flatMap(Observable::from)
            .subscribe(item -> {

            });

Si vous souhaitez combiner ces deux méthodes et transformer toutes les valeurs en un seul endroit tout en les émettant une par une, vous pouvez procéder de la manière suivante:

    Observable.create(subscriber -> {
        for (Item item : items) {
            subscriber.onNext(transformA2B(item));
        }

        subscriber.onCompleted();
    });
13
Anton Pogonets

Vous pouvez également utiliser Observable.fromIterable (liste) pour créer une liste d'observables à partir d'une liste. Ensuite, vous pouvez parcourir les éléments et les convertir en liste.

 Observable.fromIterable(list)
            .filter(item -> item.getId().equals("SampleId")
            .toList();
0
Gerardo Suarez
Observable
    //Loop through the list and emit value one by one
    .fromIterable(intList)
    //Modify the list item to new item
    .map(listItem -> listItem + 10)
    //Update UI or do anything here
    .doOnNext(System.out::println)
    //Convert to new list after modifying each item
    .toList()
    .subscribe(
        newList -> "You will get new list",
        error -> "error"
    );
0
arungiri_10

Ici c'est .. avec un exemple simple:

public static void main(String[] args) {
    String[] s = {"a", "b", "c"};
    Observable.from(s).map(value -> "A"+value).subscribe(result -> System.out.println(result));
    Observable.timer(2, TimeUnit.SECONDS).toBlocking().subscribe();
}

Comme vous l'avez mentionné liste, j'utilise un tableau pour plus de simplicité, même une liste peut être utilisée comme paramètre pour from()

0
Pavan Kumar