RxJava - zip list of Observable

前端 未结 3 967
眼角桃花
眼角桃花 2021-02-13 02:02

I have a list of Observables (RxJava 1).

List observableList = new ArrayList<>();

It can contain at least 1 Observable.

相关标签:
3条回答
  • 2021-02-13 02:42

    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 Observables and a FuncN (which takes a varargs parameter for its call method) and uses it to combine the corresponding emitted Objects 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;
        }
    });
    
    0 讨论(0)
  • 2021-02-13 02:46

    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!

    0 讨论(0)
  • 2021-02-13 03:04

    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!

    0 讨论(0)
提交回复
热议问题