简体   繁体   中英

How to process first n items and remaining one differently in a observable stream

for example,

given a stream of a certain number (m) of numbers (m1, m2, m3, m4, m5, m6...), and apply a transformation (2 * i) to first n items (n can be less, equal or larger than m), apply another transformation (3 * i) to the remaining items. and

return result : m1*2, m2*2, m3*3, m4*3, m5*3, m6*3... (assuming n=2 here).

I was trying to use take(n) and skip(n) and then concatwith, but looks like take(n) will drop the remaining items in the sequence , and make skip(n) after that return nothing.

You can share your m's stream, and then merge back together take() and skip() streams, something like this:

    int m = 10;
    int n = 8;
    Observable<Integer> numbersStream = Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
            .publish();

    Observable<Integer> firstNItemsStream = numbersStream.take(n)
            .map(i -> i * 2);

    Observable<Integer> remainingItemsStream = numbersStream.skip(n)
            .map(i -> i * 3);

    Observable.merge(firstNItemsStream, remainingItemsStream)
            .subscribe(integer -> System.out.println("result = " + integer));
    numbersStream.connect();

EDIT:
As point out by @AE Daphne, share() will start emitting with the first subscriber, thus second subscriber might miss notification/s if the Observable started already to emit item/s, so in this case there are other possibilities:
cache() - will reply all cache emitted items and reply them to each new subscriber, but will sacrifice the unsubscription ability, thus need to be used carefully.
reply().refCount() - will create Observable that reply() all previous items to each new Subscriber (similar to cache), but will unsubscribe when the last subscriber unsubscribe from it.

In both cases, memory should take into consideration as the Observable will cache all emitted items in memory.

publish() - Additional possibility, without caching all previous items, would be to use publish() to create ConnectableObservable , and call it's connect() method to begin emissions after all required subscribers subscribed, thus will get synchronization and all subscribers will get all notifications correctly.

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