Сочетание результатов нескольких наблюдаемых

Я пытаюсь добиться чего-то вроде этого: – Сделайте два разных вызова API и объедините результаты в список. Результат для каждого вызова – это HashMap, и у меня есть функция, чтобы преобразовать его в список. Сейчас я пытаюсь объединить списки в один, но у меня возникают трудности.

Это то, что выглядит моя служба 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>> 

Я смог сделать вызовы отдельно и преобразовать результат в список (пожалуйста, поправьте меня, если это можно сделать лучше) следующим образом:

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

Это функция, которая преобразует результат в список:

  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; } 

Теперь я хочу объединить списки из обоих вызовов, а затем сохранить их в базу данных. Как это сделать с RxJava?

Я пробовал что-то вроде этого, но я продолжаю получать сообщения об ошибках:

  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(); 

Используя zip оператор, вы можете комбинировать результат как Single и применить функцию преобразования, которая возвращает список

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

Ответ gyosida правильный. Вот еще один пример, показывающий общее использование 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 }) 

Счастливое кодирование!

Intereting Posts
Как установить конфигурации package.json с помощью kotlin-frontend-plugin как настроить регистратор логов Получение NoClassDefFoundError при вызове функции расширения kotlin Как проверить функции расширения Kotlin? Как добавить вторичную легенду в диаграмму JavaFX? Мое собственное решение для отсутствия пробных ресурсов Котлина Ошибка при смене лямбды для плоской карты из двух наблюдений на плоскую карту двух синглов Котлин не может получить доступ к защищенному абстрактному методу Поведение с функциями высшего порядка Котлина и интерфейсами с одним методом? Как представить вложенную @Relation с помощью Android Room? объекты закрытого класса, загадочно становящиеся нулевыми, если ссылаются на другие объекты-компаньоны Анализ дат Java RealmMigrationNeededException при добавлении RealmList <Int> (Kotlin) Android, тест Espresso не может работать с записью активности на Kotlin Я не могу инициализировать свой массив (MutableList) в классе на Android