Don Code
Don Code

Reputation: 888

What is the most efficient way of combining many Single<List<Type>>'s into a Single<List<Type>>?

I have a function loadApplesById that accepts an AppleId and returns a Single<List<Apple>>.

In another function, loadApplesByIdList I accept a List<AppleId> as a parameter. And for each element in it I have to call loadApplesById. The loadApplesByIdList will also return a Single<List<Apple>>.

Something like this:

Single<List<Apple> loadApplesById(AppleId appleId)
{
    // magic to create and load the apple list.
    return the Single.just(AppleList);
}


Single<List<Apple> loadApplesByIdList(List<AppleId> appleIdList)
{
    // My question how to create this function (?)
    // Approach (1)
    return Observable.from(appleIdList).flatMap(
        appleId -> this.loadApplesById(id)
        .toObservable())
        .reduce(new ArrayList<>(), (List<Apple> a, List<Apple> b)
            -> { a.addAll(b); return a; }).toSingle();

    // Approach (2)
    return Observable.from(appleIdList).flatMap(appleId -> loadApplesById(id)
            .toObservable())
            .toSingle();

}

While both these approaches compile, neither of them works.

It would be a great learning lesson if someone would take the time to elaborate on the different ways that this could be accomplished (with fold, reduce, flatMap, concatMap) etc.

Upvotes: 1

Views: 88

Answers (1)

akarnokd
akarnokd

Reputation: 70017

You have to unroll each single, concatenate them and then collect them up again:

Single<List<Apple>> allApples = 
    Observable.fromIterable(appleIdList)
    .concatMap(appleId -> 
         loadApplesById(appleId)
         .flattenAsObservable(list -> list)
    )
    .toList();

You'll need RxJava 2 for this though.

Upvotes: 1

Related Questions