Группировка и объединение наблюдаемых в RxJava - PullRequest
0 голосов
/ 31 октября 2019

Я хотел бы сделать следующее с RxJava

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

ниже приведен пример monthInvoices: список для обработки

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

Сначала я бы хотел сгруппировать егок следующему дню месяца, например:

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

Затем я хотел бы создать список, содержащий все дни месяца. Скажем, у нас есть 30 дней для этого месяца, тогда в выходной список необходимо вставить пустой объект Invoice с нулевой суммой для дней, в которых нет счета

Требуемый список вывода

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)

Надеюсь, я объяснил необходимость четко. Может кто-нибудь, пожалуйста, ответьте мне решение сделать это полностью с помощью RxJava?

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Попробуйте это

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) }
        }
0 голосов
/ 31 октября 2019

Этого можно достичь гораздо проще, используя операторы коллекции в стандартной библиотеке Kotlin, но в чистом RxJava вы можете сделать это, используя groupBy и 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)
        }
...