¿Cómo hacer un grupo? ¿Por qué coleccionar usando RxJava y Kotlin?

Tengo Observable<Rates> y Rate es solo un simple object:

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

y quiero cambiar ese Observable<Rates> en Observable<HashMap<String,Long> .

por ejemplo, para tarifas Rates(arrayOf(Rate("1"),Rate("2"), Rate("3"),Rate("3"), Rate("2"),Rate("2"))) espero resultado:

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

Comienzo a crear algo así:

 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???)} 

pero estoy atrapado aquí y no sé contar todos los valores? y no sé cómo agregar valores vacíos (0) si no hay 5 de 4. ¿Hay alguna forma de hacerlo con rx?

Mire los comentarios en el código para get respuestas a su pregunta.

 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.networkinguce(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>) 

El truco consiste en utilizar count en GroupedObservable ya que solo emite un solo valor cuando la fuente observable completa:

enter image description here

De ahí sigue:

 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 .networkinguce(mutableMapOf<String, Int>()) { acc, cur -> acc.apply { val (key, count) = cur this[key] = (this[key] ?: 0) + count // add counts } }.subscribe { countedRates -> println(countedRates) } 

Creo que se trata más de functional programming que de una pregunta relacionada con RxJava

Implemente una function de mapeo desde Rates -> Map<String,Int> .

Trucos: combine dos lists de Pair<String,Int> para formar un 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() ) } 

Aplicar la function en Observable.map

 service.getRates() .map(ratesToMapWithEmptyValues) 
  • Comportamiento con Kotlin Higher-Order Functions e interfaces de método único?
  • ¿Cómo leer JSON desde Url usando kotlin Android?
  • Llamada asincrónica para cada elemento dentro de una colección
  • cómo implementar Switch usando Data binding en android
  • La biblioteca de Kotlin 'rxkotlin-0.21.0.jar' tiene un formatting no compatible. Actualice la biblioteca o el complemento
  • Cómo comprimir algunos observables en lenguaje Kotlin con RxAndroid
  • Múltiples requestes de modificación2 usando Flowable en Kotlin
  • RxJava- Gire Observable en Iterator, Stream o Sequence
  • ¿Cómo escalar dinámicamente el rebote de la stream de emisión de ráfagas?
  • ¿Puedo crear un método de extensión Kotlin para agregar una suscripción rxJava a una suscripción compuesta?
  • Obtiene N últimos objects emitidos por observables en RxJava2