Search code examples
rx-java2

Grouping and Combining Observables in RxJava


I would like to do the following with RxJava

class Invoice(val dayOfMonth:Int,val amount:Int)

below is the sample monthInvoices:List< Invoice > to process

Invoice(3,100)
Invoice(3,150)
Invoice(3,50)
Invoice(4,350)
Invoice(8,400)
Invoice(8,100)

First, I would like to group it by the day of the month like the following

Invoice(3,300)
Invoice(4,350)
Invoice(8,500)

Then I would like to create a list containing all the days of the month. Say, we are having 30 days for this month, then the output list must contain inserting a empty Invoice object with 0 amount for the days where there is no invoice

Desired output List

Invoice(1,0) //Since day 1 is not in the group summed list
Invoice(2,0) //day 2 is also not there
Invoice(3,300)
Invoice(4,350)
Invoice(5,0) 
Invoice(6,0)
Invoice(7,0)
Invoice(8,500)
…..
Invoice(30,0)

Hope I have explained the need clearly. Can anyone please answer me a solution to do it entirely using RxJava?


Solution

  • Try this

    fun task(invoices: List<Invoice>) =
        Observable.fromIterable(invoices)
            .groupBy { it.dayOfMonth }
            .flatMapSingle { group -> group.reduce(0) { t1, t2 -> t1 + t2.amount }
                .map { group.key to it }}
            .toMap({ it.first }, { it.second })
            .flatMapObservable { map ->
                Observable.range(1, 30)
                    .map { Invoice(it, map[it] ?: 0) }
            }