J'ai une liste d'observables (RxJava 1).

List<Observable> observableList = new ArrayList<>();

Il peut contenir au moins 1 observable. Chacun a le même type de résultat.

Comment puis-je compresser les résultats de tous les observables?

J'ai pensé à l'opérateur zip mais il ne supporte pas List et je ne connais pas la quantité d'observables (ça peut être 1,2,3,4 ....)

13
asf 20 avril 2017 à 19:10

3 réponses

Meilleure réponse

Vous pouvez utiliser le zip(java.lang.Iterable<? extends Observable<?>> ws,FuncN<? extends R> zipFunction) méthode.

C'est une méthode zip qui prend un Iterable de Observable s et un FuncN (qui prend un paramètre varargs pour son {{ X4}}) et l'utilise pour combiner les Object émises correspondantes dans le résultat à omettre par le nouveau Observable renvoyé.

Ainsi, par exemple, vous pouvez faire:

Observable.zip(observableList, new FuncN(){
    public ReturnType call(java.lang.Object... args){
        ReturnType result; //to be made
        //preparatory code for using the args
        for (Object obj : args){
            ReturnType retObj = (ReturnType)obj;
            //code to use the arg once at a time to combine N of them into one.
        }
        return result;
    }
});
17
Community 23 mai 2017 à 12:34

J'ai également eu du mal avec cela et j'ai utilisé la solution de Sharan comme base pour la mienne.

Mon cas d'utilisation était de faire des appels d'API à plusieurs fournisseurs tiers, puis de mettre chaque résultat individuel dans une liste. Chaque élément de la liste contient ce que l'API a renvoyé, qu'il s'agisse d'un succès ou d'un échec.

En fin de compte, il a l'air assez élégant. Dans mon cas spécifique, "ResultType" a été remplacé par quelque chose comme "ApiGenericResponseObject".

Observable.zip(listOfObservables, args -> {
    List<ResultType> result = new ArrayList<>();
    for (Object o: args) {
        ResultType c = (ResultType) o;
        // additional code here, I am just concatenating them together
        // This gives me a list with the individual result of each Observable (for instance an API call)
        result.add(c);
    }
    return result;
});

Alternativement, en tant que Lambda, il a l'air plus soigné. Bien que je me demande si quelqu'un lisant ceci comprendra ce qui se passe:

Observable.zip(listOfObservables, args -> Arrays.stream(args)
    .map(object -> (ResultType) object)
    .collect(Collectors.toList())
);

J'espère que cela aide!

0
Pim 27 mars 2020 à 11:31

ReactiveX - Opérateur Zip

Zip au-delà de BiFunction

Zip combine les émissions de plusieurs observables ensemble via une fonction spécifiée et émet des éléments uniques pour chaque combinaison en fonction des résultats de cette fonction

Ici, la liste est une liste de tableaux d'observables du type que vous voulez passer.

val list = arrayListOf<Observable<ImageUrlResponse>>()


Observable.zip(list) { args -> Arrays.asList(args) }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
        val response = it[0]
        val imageUrlResponse = imageUrlObject as ImageUrlResponse
        urls.add(imageUrlResponse.imageUrl)}
               }, {
        val c = it
 })

Le résultat de l'abonnement suivant est cette image ci-dessous. Tout comme nous nous attendons à ce qu'il soit compressé ensemble . Vous remarquerez également qu'il renvoie toutes les réponses à compresser dans un seul java.lang.Object [] .

Notez que j'ai dû taper cast ma liste de tableaux pour accéder à mon seul objet, car il est de type Any!

enter image description here

10
Sharan 20 déc. 2018 à 13:23