Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten Observable<Observable<Cursor>> to Observable<Cursor>

I've an Observable that returns a single Cursor instance (Observable<Cursor>). I'm trying to utilize ContentObservable.fromCursor to obtain every cursor's row in onNext callback.

One of the solutions I've figured out is such construction:

ContentObservable.fromCursor(cursorObservable.toBlocking().first())
    .subscribe(cursor -> {
        // map to object 
        // add to outer collection
    }, e -> {}, () -> { 
        // do something with list of objects (outer collection)
    });

This looks rather like a hack because of toBlocking().first(), but it works. I don't like it because most of the processing is done in onNext callback and we've to create outer collection to hold the intermediate results.

I wanted to use it like this:

cursorObservable.map(ContentObservable::fromCursor)
    .map(fromCursor -> fromCursor.toBlocking().first())
    .map(/* map to object */)
    .toList()
    .subscribe(objects -> {
        // do something with list of objects
    }

This still utilizes toBlocking().first() and doesn't work because once the fromCursor observable has finished the cursor is closed so there's no way to map it to object. Is there a better way to flatten Observable<Observable<Cursor>> to Observable<Cursor>?

like image 875
tomrozb Avatar asked May 06 '15 11:05

tomrozb


1 Answers

Is there a better way to flatten Observable<Observable<Cursor>> to Observable<Cursor>?

Yes, you can use Observable.concat method:

public static void main(String[] args) {
    final Observable<String> observable = Observable.just("1", "2");
    final Observable<Observable<String>> nested = observable.map(value -> Observable.just(value + "1", value + "2"));
    final Observable<String> flattened = Observable.concat(nested);

    flattened.subscribe(System.out::println);
}

UPDATE

There are actually some other methods to transform an Observable<Observable<Cursor>> to Observable<Cursor>:

  • Observable.concat
  • Observable.merge
  • Observable.switchOnNext

Just choose one that is more appropriate to you.

UPDATE 2

Another solution is to modify your code a bit and use a flatMap operator instead of map:

cursorObservable.flatMap(ContentObservable::fromCursor)
    .map(/* map to object */)
    .toList()
    .subscribe(objects -> {
        // do something with list of objects (outer collection)
    }
like image 127
Vladimir Mironov Avatar answered Nov 15 '22 03:11

Vladimir Mironov