Home > Blockchain >  How to transform Flow<List<Flow<T>>> to Flow<List<T>>
How to transform Flow<List<Flow<T>>> to Flow<List<T>>

Time:11-19

I have database query that returns the list of indexes of objects for a certain day, i.e.:

getIndexesOfDay(day: Day): Flow<List<String>>

Now, I need to listen for details for each index, for instance:

getDetailsByIndex(index: String): Flow<Details>

So the question is: how can I accomplish this using Flows?]

Two important constraints:

  1. Changes on the indexes should propagate to the final flow;
  2. Changes on any Details object should also update the flow.

What I have already tried:

getIndexesOfDay(todayDay)
          .map { indexes ->
              indexes?.map {
                      mIndex->
                  getDetailsByIndex(mIndex)
              }
          }

But it returns a Flow<List<Flow<Details>>> instead of the desired Flow<List<Details>>

Appreciate any help!

CodePudding user response:

The following should work:

getIndexesOfDay(todayDay).map { indexes ->
    indexes.flatMap { mIndex -> getDetailsByIndex(mIndex).toList() }
}

Additionally, you don't need a safe call at indexes?. because it is guaranteed that indexes will never be null.

CodePudding user response:

I think this would do it, but I haven't tested. The transform operator is more flexible than map. You can decide what and how much to emit into a new flow, so here I used combine to get the behavior you described of any change to any of the details triggering a new emission of the whole list.

getIndexesOfDay(todayDay)
    .transform {
        val detailsFlows = it.orEmpty().map(::getDetailsByIndex)
        combine(*detailsFlows.toTypedArray()) { detailsArray ->
            detailsArray.asList()
        }.onEach { detailsList ->
            emit(detailsList)
        }.collect()
    }
  • Related