简体   繁体   中英

How do I combineLatest an Observable<Observable<T>>?

I have an Observable<Observable<String>> c . I would like to combine each inner Observable into one String with new-lines. The result should be Observable<String> .

There is a similar discussion for RxJS on GitHub .

Here is an implementation using zip :

final Observable<String> d = Observable.zip(c, objects -> Arrays.stream(objects)
    .map(x -> (String)x)
    .collect(Collectors.joining("\n")));

The problem is that zip pairs elements, so if the inner Observable objects are of different lengths, then not everything gets shown. I would like to use combineLatest instead, but there does not seem to be a matching function:

public static <T, R> Observable<R> combineLatest(
    ObservableSource<? extends ObservableSource<? extends T>> sources, 
    Function<? super Object[], ? extends R> zipper)

How should I implement this?


For example, if I have three observables:

// a
Observable.just("Started", "0%", "5%", "10%", "20%", "40%", "95%", "100%", "Finished")

// b 
Observable.just("Started", "0%", "10%", "30%", "40%", "100%", "Finished")

// c
Observable.just("Started", "0%", "20%", "25%", "40%", "70%", "90%", "100%", "Finished")

Then the output of my zip solution is:

---------------------
a: Started
b: Started
c: Started
---------------------
a: 0%
b: 0%
c: 0%
---------------------
a: 5%
b: 10%
c: 20%
---------------------
a: 10%
b: 30%
c: 25%
---------------------
a: 20%
b: 40%
c: 40%
---------------------
a: 40%
b: 100%
c: 70%
---------------------
a: 95%
b: Finished
c: 90%

But the desired output is something like:

---------------------
a: Started
b: Started
c: Started
---------------------
a: 0%
b: 0%
c: 0%
---------------------
a: 5%
b: 10%
c: 20%
---------------------
a: 10%
b: 30%
c: 25%
---------------------
a: 20%
b: 40%
c: 40%
---------------------
a: 40%
b: 100%
c: 70%
---------------------
a: 95%
b: Finished
c: 90%
---------------------
a: 100%
b: Finished
c: 100%
---------------------
a: Finished
b: Finished
c: Finished

Using RxJava2 (and Java 8)

c.toList().toObservable()
          .flatMap(t -> 
                  Observable.combineLatest(t, 
                                           objects -> Arrays.stream(objects)
                                                            .map(x ->(String)x).collect(Collectors.joining("\n"))))

Using RxJava

c.toList().flatMap(t -> 
                  Observable.combineLatest(t, 
                                           objects -> Arrays.stream(objects)
                                                            .map(x -> (String)x).collect(Collectors.joining("\n"))));

I doubt it will do exactly what you want though because it is entirely possible it will "skip" emissions but that's the way combineLatest works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM