【问题标题】:Flow.take(ITEM_COUNT) returning all the elements rather then specified amount of elementsFlow.take(ITEM_COUNT) 返回所有元素而不是指定数量的元素
【发布时间】:2022-01-20 15:16:30
【问题描述】:

我有一个方法 X,它通过 pub sub 从服务器获取数据。此方法返回一个流。我有另一种方法,它通过方法 X 订阅流,但如果数据与以前的数据不同,则只想从流中获取前 3 个最大值。我写了以下代码

fun subscribeToData() : Flow<List<MyData>> {
    ....
    //incoming data
    emit(list)
}

fun getUptoFirst3Items() {
   subscribeToData()
   .take(ITEM_COUNT) // ITEM_COUNT is 3
   .distinctUntilChange() //only proceed if the data is different from the previous top 3 items
   .mapIndex {
     //do transformation
   }
   .collect { transformedListOf3Elements ->
    
   }

}

问题:

在 collect{} 中,我获取的不是 3 个元素,而是流中传入的所有数据。

我不确定这里有什么问题?有人可以帮我吗?

【问题讨论】:

  • 能否分享更多subscribeToData的实现?

标签: kotlin operators flow


【解决方案1】:

@Joffrey 的回答已经解释了为什么您会返回整个列表,并建议您在列表本身上使用 take()。

如果您只想从每个发出/观察的列表中获取第一个 ITEM_COUNT 元素,那么您必须映射结果并且每次仅从列表中获取 ITEM_COUNT 项目,而不是获取 ITEM_COUNT流程中的项目。

fun getUptoFirst3Items() {
   subscribeToData()
   .map {
     // in Kotlin stdlib Iterable<T> has an extension method take(n: Int)
     // that will return a List<T> containing the first n element from the iterable
     it.take(ITEM_COUNT)
     // alternatively you can also use subList, but the semantics are not the same,
     // so check the subList documentation, before using it
     it.subList(0, ITEM_COUNT)
   }
   .distinctUntilChange() //only proceed if the data is different from the previous top 3 items
   .mapIndex {
     //do transformation
   }
   .collect { transformedListOf3Elements ->
    
   }

}

【讨论】:

    【解决方案2】:

    你在这里有一个Flow&lt;List&lt;MyData&gt;&gt;,这意味着这个流的每个元素本身就是一个列表。

    take 运算符应用于流,因此您将获取流的前 3 个列表。每个单独的列表不受限制,除非您在列表本身上使用take。

    所以名称transformedListOf3Elements 是不正确的,因为该列表包含未知数量的元素,除非您在map 中以某种方式对其进行过滤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-30
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多