Как сделать groupBy и собирать с помощью RxJava и Kotlin?

У меня есть Observable<Rates> и Rate – просто простой объект:

 Rate(val value:String){} Rates(val rates: List<Rate>) 

и я хочу изменить этот Observable<Rates> в Observable<HashMap<String,Long> .

например, для ставок Rates(arrayOf(Rate("1"),Rate("2"), Rate("3"),Rate("3"), Rate("2"),Rate("2"))) Я ожидаю результата:

 (1 -> 1) (2 -> 3) (3 -> 2) (4 -> 0) (5 -> 0) 

Я начинаю создавать что-то вроде этого:

 service.getRates() .flatMap {it-> Observable.from(it.rates) } .filter { !it.value.isNullOrEmpty() } .groupBy {it -> it.value} .collect({ HashMap<String,Long>()}, { b, t -> b.put(t.key, t.count???)} 

но я застрял здесь, и я не знаю, чтобы подсчитать все значения? и я не знаю, как добавить пустые значения (0), если нет 5 из 4. Есть ли способ сделать это с помощью rx?

Пожалуйста, ознакомьтесь с комментариями в коде для ответов на ваш вопрос.

 import rx.Observable fun main(args: Array<String>) { val service = Service() // This adds all keys with each key mapped to zero val referenceKeyCounts = Observable .just("1", "2", "3", "4", "5") .map { it to 0 } val keyCountsFromService = service.getRates() .flatMap { Observable.from(it.rates) } .filter { !it.value.isNullOrEmpty() } .map { it.value to 1 } // map each occurrence of key to 1 Observable.concat(referenceKeyCounts, keyCountsFromService) .groupBy { it.first } .flatMap { group -> // this converts GroupedObservable to final values group.reduce(0, { acc, pair -> acc + pair.second }) // add instead of counting .map { group.key to it } } .subscribe(::println) } class Service { fun getRates(): Observable<Rates> = Observable.just(Rates(listOf( Rate("1"), Rate("2"), Rate("3"), Rate("3"), Rate("2"), Rate("2") ))) } class Rate(val value: String) class Rates(val rates: List<Rate>) 

Хитрость заключается в том, чтобы использовать count для GroupedObservable поскольку он генерирует только одно значение, когда завершается исходный наблюдаемый:

введите описание изображения здесь

Отсюда следует:

 rates .flatMap { Observable.from(it.rates) } .filter { !it.value.isNullOrEmpty() } .groupBy { it.value } .flatMap { group -> group.count().map { group.key to it } } // list "1"->1, "2"->3, ... .mergeWith(Observable.from((1..5).map { it.toString() to 0 })) // defaults "4"->0 .reduce(mutableMapOf<String, Int>()) { acc, cur -> acc.apply { val (key, count) = cur this[key] = (this[key] ?: 0) + count // add counts } }.subscribe { countedRates -> println(countedRates) } 

Я думаю, что это скорее функциональное программирование, чем вопрос, связанный с RxJava

Реализовать функцию сопоставления из Rates -> Map<String,Int> .

Трюки: объедините два списка Pair<String,Int> чтобы сформировать Map<String,Int>

 val ratesToMapWithEmptyValues: (Rates) -> Map<String, Int> = { source -> //TODO: Just for demo val validRatesValue = arrayOf("1","2","3","4","5") mapOf( *validRatesValue.map { it to 0 }.toTypedArray(), *source.rates.groupBy(Rate::value).mapValues { it.value.size }.toList().toTypedArray() ) } 

Применить функцию в Observable.map

 service.getRates() .map(ratesToMapWithEmptyValues) 
Intereting Posts
Обертывание всех внутренних методов одним и тем же пробником в Котлине Оператор «Когда» и «switch» оператора Java Метод обмотки React-Kotlin setState TornadoFX: разрешить копирование элемента из списка в буфер обмена Как сделать плагин идеи в градле генерировать правильную конфигурацию проекта для Kotlin? Как высмеять окончательный класс с mockito Преобразование единиц измерения в километры до миль не возвращает ожидаемый результат как получить информацию, используя библиотеку волейбола в Котлине Могу ли я использовать два xml-макета для использования одного и того же зрителя с использованием синтетических расширений Kotlin? Вывод типичного типа Карты в Котлин Kotlin Twitter Outh-Signature как установить цвет RecyclerView.ViewHolder в BroadcastReceiver.onReceive? Инициализация RecyclerView с привязкой данных Android в Котлине вызывает ошибку. Что я делаю не так? Как Kotlin взаимодействует с Java и JavaScript? Как я могу сделать разрыв строки (продолжение строки) в Котлине