Search code examples
javaandroidrx-javarx-java3

RxJava: how to use Observable instead nested loops?


Now I use nested loops with ReplaySubject to get multiple observables and this need to be converted without using any loops, just observables.

private Observable<BaseUnit> getUnitObservables(ArrayList<Map<Integer, Integer>> list, ReplaySubject<BaseUnit> subject) {

    ArrayList<Observable<BaseUnit>> observables = new ArrayList<>();
    
    for (Map<Integer, Integer> elem : list) {
        for (MapOperationName operationName : MapOperationName.values()) { // MapOperationName type is enum

            Observable<BaseUnit> observable = Observable.fromCallable(() -> {
                // some operations here

                subject.onNext(unit);
                observables.add(observable);
            });
        }
    }
    return Observable.merge(observables);
}

"Map<Integer, Integer> elem : list" has 3 elements. "MapOperationName.values()" return 7 elements. So totally should be 21 as I get in example above.

Trying to refactor something like this but get only 3 elements:

private Observable<BaseUnit> getUnitObservables(ArrayList<Map<Integer, Integer>> list, ReplaySubject<BaseUnit> subject) {

    Observable<ListOperationName> observableOperation = 
    Observable.fromArray(MapOperationName.values());
    Observable<List<Integer>> observableList = Observable.fromIterable(list);
    return Observable.zip(observableList, observableOperation, (listElem, operationElem) -> {

        subject.onNext(unit);
        //some operations here
    });

}

How to combine correctly this ArrayList and Enum to get full set of pair combination?


Solution

  • You can nest the operations you need to do inside of a flatMap to achieve this:

    private Observable<BaseUnit> getUnitObservables(ArrayList<Map<Integer, Integer>> list, ReplaySubject<BaseUnit> subject) {
    
        Observable<ListOperationName> observableOperation = 
            Observable.fromArray(MapOperationName.values());
        Observable<List<Integer>> observableList = Observable.fromIterable(list);
        return observableList
            .flatMap(listElem -> observableOperation
                .map(operationElem -> {
                    // some operations here
                    subject.onNext(unit);
                    return unit;  // Assuming unit is a BaseUnit
                })
            );
    }