【问题标题】:How to filter a list inside Kotlin Flow如何过滤 Kotlin Flow 中的列表
【发布时间】:2019-12-22 14:30:17
【问题描述】:

我将使用 RxJava 替换为 CoroutinesFlow 的当前实现。我在使用一些 Flow 运算符时遇到了一些问题。

我正在尝试过滤 Flow 中的项目列表,然后再提供它以供收集。 (Flow<List<TaskWithCategory>>)

这是Rx2上的示例:

        repository.findAllTasksWithCategory()
            .flatMap {
                Flowable.fromIterable(it)
                    .filter { item -> item.task.completed }
                    .toList()
                    .toFlowable()

在上面的实现中,我提供了一个由Tasks 过滤的TaskWithCategory 列表,这些过滤器已经完成。

如何使用Flow 实现这一目标?

【问题讨论】:

    标签: kotlin-coroutines kotlinx.coroutines.flow


    【解决方案1】:

    鉴于唯一使用的运算符是filter,内部的flowable 是不必要的,使得流实现非常简单:

    repository.findAllTasksWithCategoryFlow()
        .map { it.filter { item -> item.task.completed } }
    

    如果内部转换涉及更多(让我们使用transform: suspend (X) -> TaskWithCategory):

    repository.findAllTasksWithCategoryFlow()
        // Pick according to desired backpressure behavior
        .flatMap(Latest/Concat/Merge) {
            // Scope all transformations together
            coroutineScope {
                it.map { item ->
                    // Perform transform in parallel
                    async {
                        transform(item)
                    }
                }.awaitAll() // Return when all async are finished.
            }
        }
    

    【讨论】:

    • flatMapMerge 的工作方式比您展示的要简单得多,您需要提供一个Flow-returning 函数,它会自动并行化这些流的集合。 tasksFlow.flatMapMerge { flow { emit(it.map { transform(it) }) } }
    • 这将并行处理不同的列表,而我的版本并行处理单个列表中的所有项目。
    • 没错,但是在单独的协程中处理每个单独的项目通常会损害性能,除非处理每个项目真的很繁重。另外,在这种情况下,我认为您没有正确使用flatMapMerge,您没有使用它提供的自动并发。您可以使用普通的 mapflatMap 获得相同的结果。
    猜你喜欢
    • 2016-08-05
    • 1970-01-01
    • 2017-11-24
    • 2019-01-17
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    相关资源
    最近更新 更多