Combinando los resultados de múltiples observables

Estoy tratando de lograr algo como esto: – Hacer dos llamadas API diferentes y combinar los resultados en una list. El resultado de cada llamada es un HashMap y tengo una function para convertirlo en una list. Lo que trato de hacer ahora es combinar las lists en una, pero estoy teniendo dificultades.

Este es el aspecto de mi service Retrofit:

@GET("data/price?fsym=ETH") fun getETHRates(@Query("tsyms") tsyms : String) : Single<HashMap<String, Double>> @GET("data/price?fsym=BTC") fun getBTCRates(@Query("tsyms") tsyms: String) : Single<HashMap<String, Double>> 

He podido realizar las llamadas por separado y transformar el resultado en una list (corrígeme si esto se puede hacer mejor) de esta manera:

  val btcRates: Single<List<Currency>> = cryptoApi.getBTCRates(countries) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .flatMap { result: HashMap<String, Double> -> return@flatMap Single.just(createCurrencyObjects ("BTC", result)) } val ethRates: Single<List<Currency>> = cryptoApi.getETHRates(countries) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .flatMap { result: HashMap<String, Double> -> return@flatMap Single.just(createCurrencyObjects("ETH", result)) } 

Esta es la function que transforma el resultado en una list:

  fun createCurrencyObjects(from: String, map: HashMap<String, Double>): List<Currency> { val list = ArrayList<Currency>(0) for (key in map.keys) { val amount: Double? = map.get(key) list.add(Currency(0, from, key, amount!!)) } return list; } 

Lo que quiero hacer ahora es combinar las lists de ambas llamadas y luego savelas en una database. ¿Cómo hago esta combinación con RxJava?

Intenté algo así, pero sigo recibiendo posts de error:

  val apiCall: Disposable = Observable.concat(ethRates, btcRates) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { values: List<Currency> -> run { App.database?.currencyDao()?.insertAllCurrencies(values) } } .doOnError { e -> e.printStackTrace() } .subscribe(); 

Usando el operador zip puedes combinar el resultado de ambos Single y aplicar una function transformadora que devuelve una list

 Single.zip( rates1, rates2, BiFunction<List<Currency>, List<Currency>, List<Currency>> { x, y -> // return your list } ).doOnSuccess { list -> // save your data } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) 

La respuesta de gyosida es correcta. Aquí hay otro ejemplo que muestra un uso genérico de Zip:

  val single1 = Single.just(mutableListOf("one", "two", "three")) val single2 = Single.just(mutableListOf("four", "five", "six")) val single = Single.zip(single1, single2, BiFunction { a: MutableList<String>, b: MutableList<String> -> a.addAll(b) return@BiFunction a }) 

Feliz encoding!

  • IncompatibleClassChangeError: Class 'java.lang.VirtualMachineError' no implementa la interfaz 'java.lang.CharSequence'
  • Manejo de tipo anulable en RxJava con Kotlin
  • Kotlin: cómo henetworkingar del suscriptor de RxJava
  • Clasificación de objects alfanuméricamente
  • ¿Hay alguna manera de cambiar mi método a la stream Observable que será una cadena de modificadores?
  • Observable.just () que devuelve Unidad en Kotlin
  • Excepción: blockingConnect no se debe invocar en el subprocess UI a pesar de que subsubscribí en otro subprocess
  • Comportamiento con Kotlin Higher-Order Functions e interfaces de método único?
  • Espere hasta que dos observables emitan verdadero
  • Argumento de tipo explícito Kotlin y RxJava
  • ¿Cómo se coordina una list de ejecuciones Completables con RxJava?