Как объединить два kotlin объекта данных с общей переменной в один объект? - PullRequest
0 голосов
/ 25 мая 2020

Я делаю небольшое приложение, которое отслеживает значения криптовалюты на бирже Bittrex.

Для этого я использую Bittrex 'publi c api (https://bittrex.github.io/api/v3) К сожалению API не предоставляет данные, которые мне нужны, с помощью всего одного вызова, поэтому мне нужно сделать два вызова API.

Я хочу получить один объект, содержащий все следующие значения:

  • символ (это общее значение для обоих вызовов API, поэтому оно должно совпадать)
  • quoteVolume
  • percentChange
  • lastTradeRate

Переменная, выделенная жирным шрифтом, является частью одного вызова API, другие значения - частью другого. «Символ» является частью обоих.

Я использую kotlin сопрограммы и надеялся, что мне не нужно использовать что-то вроде Rx Java, чтобы заставить это работать.

    CoroutineScope(IO).launch {
        val tickers = async {
            api.getTickers()
        }.await()

        val markets = async {
            api.getMarkets()
        }.await()
        val result = mutableListOf<Market>()
        for (ticker in tickers.data) {
            for (market in markets.data) {
                if (ticker.symbol == market.symbol) {
                    result.add(
                        Market(
                            ticker.symbol,
                            ticker.lastTradeRate,
                            market.quoteVolume,
                            market.percentChange
                        )
                    )
                }
            }
        }
    }

1 Ответ

1 голос
/ 25 мая 2020

Вы можете сделать 2 вызова параллельно, используя сопрограммы.

Предполагая, что firstApi и secondApi являются функциями приостановки, которые возвращают данные для каждого из 2-х блоков информации, которые вам нужны,

val data1Deferred = async { firstApi() }
val data2Deferred = async { secondApi() }
val data1 = data1Deferred.await()
val data2 = data2Deferred.await()
val result = Result(
    // build result from data1 and data2
)

Вам также потребуется добавить обработку ошибок.

Изменить:

вы можете сгруппировать свой список по символу и создать карту:

val marketMap = markets.associateBy { it.symbol }

Тогда для каждого тикера можно получить соответствующий рынок

for (ticker in tickers) {
    val market = marketMap[ticker.symbol]
    if (market != null) {
        // join ticker and market
    }
}
...