我正在用这样的rxjava2制作一系列事件。
Observable<Integer> observable = booleanPublisher.map(aBoolean -> {
if(aBoolean){
return 1;
}else{
return 0;
}
}).buffer(4).map( aLilst ->{
int sum = 0;
for (Integer i: aLilst) {
sum +=i;
}
return sum;
});
observable.subscribe(
aInt ->{
Log.v("Value",String.valueOf(aInt));
}
);
这会产生一个int事件流,其值为0..4,现在我想过滤这个事件,当例如一行中的2个整数事件小于4时发出一个事件,而另一个事件是连续10个具有4个值的整数事件。我试图将两个不同的可观察量分开并合并,但没有运气,因为这两个事件必须互相重置。
提前致谢。
答案 0 :(得分:1)
避免使用两种不同订阅的另一个选择是使用merge
,这样:
enum MatchResult{
TWO_ITEM_SMALL,
FIVE_CONSECUTIVE
}
Observable<MatchResult> getObservable1(Observable<Integer> observable) {
return observable
.scan(0, (integer, integer2) -> {
if (integer2 < 4) {
return integer + 1;
}
return 0;
}).filter(integer -> integer >= 2)
.map(integer -> MatchResult.TWO_ITEM_SMALL);
}
Observable<MatchResult> getObservable2(Observable<Integer> observable) {
return observable
.scan(0, (integer, integer2) -> {
if (integer2 == 4) {
return integer + 1;
} else {
return 0;
}
}).filter(integer -> integer >= 5)
.map(integer -> MatchResult.FIVE_CONSECUTIVE);
}
Observable.merge(getObservable1(getSoruce()), getObservable2(getSoruce()))
.subscribe(matchResult -> {
if(matchResult == MatchResult.TWO_ITEM_SMALL) {
logd("two items in a row, smaller than 4.");
} else {
logd("five items in a row equals to 4");
}
});
答案 1 :(得分:0)
实现它的一种方法是使用scan
运算符。正如文档所说:
“扫描”操作符将函数应用于由此发出的第一个项目 source Observable然后以该函数的形式发出该函数的结果 自己的第一次排放。
作为函数的返回值,您可以获得符合条件的行中的项目数。
我认为在单个订阅中有一种方法可以实现,但我认为通过ConnectableObservable
运算符使用publish()
将其拆分更为清晰。让我们举个例子:
Observable<Integer> getSource() {
return Observable.just(1, 2, 3, 4, 4, 4, 4, 4, 2);
}
现在我们创建一个观察者来检查两个连续的小于4个项目。
Observable<Integer> source = getSource();
source.scan(0, (integer, integer2) -> {
if (integer2 < 4) {
return integer + 1;
}
return 0;
}).filter(integer -> integer >= 2)
.subscribe(integer -> logd("two items in a row, smaller than 4."));
接收五个(为了简化)连续值的事件的订阅者等于4。
source.scan(0, (integer, integer2) -> {
if (integer2 == 4) {
return integer + 1;
}
return 0;
}).filter(integer -> integer >= 5) // for you it will be ten
.subscribe(integer -> logd("five items in a row equals to 4."));
现在你打电话:
observable.connect();
注意:当条件匹配时,当前实现不会重置计数器。这意味着,例如,如果您正在寻找一个包含五个连续值的序列,则该序列等于4:
4 4 4 4 4 4
将生成两个匹配,因为第一个匹配是序列的前五个项目,但是当您收到值为4的新项目时,您仍然匹配。