如何过滤超过增量阈值的值

时间:2018-09-19 01:34:58

标签: rx-java rx-java2

我有一个Observable发出数字(整数,双精度数,BigDecimal实际上并不重要)。我有一个在可观察的合成时间定义的阈值。换句话说,阈值在可观察的生命周期内不会改变。

我需要过滤出与阈值内最后通过的值不同的值。或改写它:仅当值与上一个传递的值相差超过阈值时,才将其传递给下游。

示例将对其进行更好的解释:

Source observable values: 
[5, 4, 7, 9, 15, 14, 13, 12, 11, 7, 3, 2, 1]

Filetered values with threshold = 3 : 
[5, 9, 15, 11, 7, 3]

为更好地说明,例如,假设它是温度读数。我只想过滤那些温度变化超过3度的值。第一个值始终会通过并用作要比较的初始值。例如,如果第一个温度读数为21摄氏度,并且在一个小时内每个后续读数都在[18..24]中,则这些值都不应向下游传递。但是,一旦越过这些界限,就应该通过并创建新的界限以进行比较。

问题是:如何仅使用RxJava运算符执行此操作?还是除了将状态存储在rx管道之外(以易失性或原子引用或任何其他同步状态,细节都没有关系)之外,别无其他方法吗?

1 个答案:

答案 0 :(得分:5)

您可以结合使用scandistinctUntilChanged仅通过RX运算符来实现此目的。

scan允许您访问上一个和下一个值,从而可以与给定的阈值进行比较。

如果未达到阈值,则可以发出前一个值。

distinctUntilChanged然后可以用来减少重复排放。

在科特林,它看起来像下面的样子:

val threshold = 3
val list = listOf(5, 4, 7, 9, 15, 14, 13, 12, 11, 7, 3, 2, 1)

return Observable.fromIterable<Int>(list)
        .scan { previous: Int, next: Int ->
            val difference = abs(next - previous)
            when {
                difference > threshold -> next
                else -> previous
            }
        }.distinctUntilChanged()