0

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?

1
  • why rx ? I do not see anything reactive in this ? why not juste Java Stream ? Commented Oct 31, 2019 at 10:53

2 Answers 2

1

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) } } 
Sign up to request clarification or add additional context in comments.

Comments

0

This can be achieved much more easily using the collection operators inside Kotlin's standard library, but in pure RxJava you can do this by using groupBy and reduce.

 val invoices = listOf( Invoice(3, 100), Invoice(3, 150), Invoice(3, 50), Invoice(4, 350), Invoice(8, 400), Invoice(8, 100) ) Observable.range(1, 30) .map { Invoice(it, 0) } // Create an Observable of Invoice([day], 0) .mergeWith(Observable.fromIterable(invoices)) .groupBy { it.dayOfMonth } // Merge the sources and groupBy day .flatMapMaybe { group -> group.reduce { t1: Invoice, t2: Invoice -> Invoice(t1.dayOfMonth, t1.amount + t2.amount) // Reduce each group into a single Invoice } } .subscribe { // Optionally you can call toList before this if you want to aggregate the emissions into a single list println(it) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.