如何将 Flow<List<Flow<T>>> 转换为 Flow<List<T>>

Ger*_*eto 7 kotlin kotlin-coroutines kotlin-flow

我有一个数据库查询,它返回某一天的对象索引列表,即:

getIndexesOfDay(day: Day): Flow<List<String>>
Run Code Online (Sandbox Code Playgroud)

现在,我需要监听每个索引的详细信息,例如:

getDetailsByIndex(index: String): Flow<Details>
Run Code Online (Sandbox Code Playgroud)

所以问题是:如何使用 Flows 来完成此任务?

两个重要的限制:

  1. 索引上的更改应该传播到最终流程;
  2. 任何对象的更改Details也应该更新流程。

我已经尝试过的:

getIndexesOfDay(todayDay)
          .map { indexes ->
              indexes?.map {
                      mIndex->
                  getDetailsByIndex(mIndex)
              }
          }
Run Code Online (Sandbox Code Playgroud)

但它返回 aFlow<List<Flow<Details>>>而不是所需的Flow<List<Details>>

感谢任何帮助!

bro*_*oot 9

我还没有测试过这一点,但我相信使用flatMapLatest()merge()应该是可能的:

getIndexesOfDay(todayDay)
    .flatMapLatest { indexes ->
        combine(indexes.map { getDetailsByIndex(it) }) { it.asList() }
    }
Run Code Online (Sandbox Code Playgroud)

对于每个新的索引列表,它会getDetailsByIndex()多次调用以获取流列表,然后将这些流组合成单个详细信息列表流。

缺点是每当索引发生更改时,它都会丢弃所有Flow<Details>对象,即使旧索引列表和新索引列表中都存在索引。最好为每个索引创建某种详细流的缓存。