RxJava - zip list of Observable
You can use the static zip(java.lang.Iterable<? extends Observable<?>> ws,FuncN<? extends R> zipFunction)
method.
It is a zip
method that takes an Iterable
of Observable
s and a FuncN
(which takes a varargs parameter for its call
method) and uses it to combine the corresponding emitted Object
s into the result to be omitted by the new returned Observable
.
So for example you could do:
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;
}
});
I struggled with this as well, and used Sharan's solution as a base for mine.
My use case was doing API calls to several 3rd party providers, and then putting each individual result in a List. Each item in the list contains what the API returned, be it success or failure.
In the end it actually looks quite elegant. In my specific case "ResultType" was replaced with something like "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;
});
Alternatively, as a Lambda it looks neater. Though I wonder whether someone reading this will understand what is going on:
Observable.zip(listOfObservables, args -> Arrays.stream(args)
.map(object -> (ResultType) object)
.collect(Collectors.toList())
);
Hope it helps!
ReactiveX - Zip operator
Zip beyond BiFunction
Zip combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function
Here, list is an Array List of Observables of whichever type you want to pass.
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
})
The Result of the following subscription is this image below. Just like we expect it to be zipped together. Also can you notice it returns all the responses to be zipped in a single java.lang.Object[].
Note I had to type cast my Array List to access my single object because it is of type Any!