【问题标题】:RxJava2: Iterate over items and get the item matching a conditionRxJava2:迭代项目并获取匹配条件的项目
【发布时间】:2019-01-10 08:16:53
【问题描述】:

在我看来,我有一个微不足道的任务,它似乎对 RX 有非平凡的解决方案。

场景:

我有一个数字生成器列表,该列表应由特定模块使用我不知道的复杂算法聚合。我可以将数字生成器的输出提供给算法。之后,我可以向算法请求一个汇总数字。

我想迭代我所有的数字生成器,直到算法返回一个符合我的条件的数字。

目前的做法:

return generators.getGenerators().flatMapObservable {
            Observable
                    .fromIterable(it)
                    .flatMap { generator: NumberGenerator ->
                        generator.getNumber()
                                .flatMapCompletable { data: NumberData ->
                                    algorithm.inject(data)
                                }
                                .andThen(algorithm.getAggregatedNumber()) 
                    }
                    .skipWhile {
                        it.value == 0.0f || it.value < minLevel
                    }
                    .firstOrError()
                    .toObservable()
        }

一些解释:

algorithm 是我班的成员。它具有上面代码使用的两个函数。 inject直接修改getAggregatedNumber返回的结果。

generators.getGenerators() 返回一个 Single>。这是Generators类的接口要求,不能改成Observable。这就是为什么我必须将它映射到 flatMapObservable 中的一个 observable。

每次我将生成器中的数字注入算法时,我都必须检查聚合数字是否符合给定条件(即达到minLevel)。如果是这样,我想返回该单个值并取消订阅剩余的生成器。

换句话说:当条件满足时,剩余的生成器不应该被“执行”,即没有 getNumber() 并且此后不应该发生 algorithm.inject。

一些假设

takeWhile 发出项目,直到满足条件并完成。不幸的是,这将跳过我感兴趣的实际项目。

skipWhile 跳过所有不感兴趣的项目并开始发出我想要的。但是,我只想要匹配条件的第一项,流的其余部分不感兴趣,因此不应发出或执行。

filter 遍历所有仅发出感兴趣项目的内容。但是,由于算法的内部原因,这与skipUntil 的工作方式相同。

simple for-loops:嗯,大部分代码都在使用 Observables 等,所以我认为当我使用 for-loops 中断流,然后从结果中重新创建 observables 时,这是一种破坏。

我希望有人可以指导我如何解决我的问题。

编辑

takeUntil 要求条件 observable 在实际满足条件时发出项目。但是,getAggregatedNumber() 会根据请求发出项目并在之后完成。没有热的 observable 总是在当前值发生变化时发出当前值,所以我可以对其应用过滤器。我怎么能用takeUntil呢?

【问题讨论】:

  • 'takeUntil` 应该可以工作。 (来自 Wiki -“此 (takeUntil) 运算符和 takeWhile(Predicate) 之间的区别在于,在这里,在发出项目后评估条件。”) - 发出项目并在检查该条件之后。不是吗?
  • 例如,使用take(1)filter() 之后获取一项。
  • takeUntil 是一种有趣的方法。如何使用它作为条件?我知道我请求直到可观察到的聚合数字并在那里过滤发出的项目?
  • 据我了解您的需求 - takeUntil 正是这样做的“我想迭代我所有的数字生成器,直到算法返回一个符合我的条件的数字。”。您将条件传递给takeUntil 运算符。 takeUntil 将传递项目,直到满足条件(包括最后一项),然后停止。
  • 我不清楚你想要什么。您想强制仅将一个元素返回给可观察对象,但该元素必须与条件匹配。我说的对吗?

标签: java android kotlin rx-java2


【解决方案1】:

我想迭代我所有的数字生成器,直到算法返回一个符合我的条件的数字。

据我了解您的需求 - 您需要使用 takeUntil(stopPredicate) 运算符。这个方法的描述说

返回一个 Observable,它发出源 Observable 发出的项目,检查每个项目的指定谓词,然后在满足条件时完成。

您将条件传递给takeUntil 运算符。 takeUntil 将传递项目直到条件满足(包括最后一项)然后停止。

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多