[英]RxJava compare different items from two observables (java 7)
我有两个Observables ob1和ob2发出项目。 如果ob1.item包含在ob2中,我想忽略它。
示例:
ob1 contains A,B,C,D
ob2 contains E,C,B,G,J,O
输出:
ob contains A,D
表达这个的最佳方式是什么?
有一个contains运算符,它返回Observable<Boolean>
,表示observable是否包含给定元素。
Observable<Boolean> contains = observable2.contains(string);
你需要的是将observable1
所有元素映射到那些boolean observables
observable1.map(new Func1<String, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(final String string) {
return observable2.contains(string);
}
})
这会给你Observable<Observable<Boolean>>
,但是很难用它。 因此,您将所有这些布尔可观察量连接成一个。 Luckilly,你需要做的就是使用concatMap
而不是map
observable1.concatMap(new Func1<String, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(final String string) {
return observable2.contains(string);
}
})
现在你有一个observable1
包含你的元素和一个Observable<Boolean>
,它包含boolean,表示observable1
的元素是否包含在observable2
observable1: A ---- B ---- C ---- D
concatMapObservable: false true true false
您可以轻松地zip
这两个可观察到可观察到的,这将传递不包含在元素observable2
并用一个空字符串代替他人
[concatMapObservable].zipWith(observable1, new Func2<Boolean, String, String>() {
@Override
public String call(final Boolean contains, final String string) {
return contains ? "" : string;
}
}
然后你过滤空字符串
[zippedObservable].filter(new Func1<String, Boolean>() {
@Override
public Boolean call(final String string) {
return !TextUtils.isEmpty(string);
}
})
整个代码放在一起:
Observable<String> observable1 = Observable.from(new String[]{"A", "B", "C", "D"});
Observable<String> observable2 = Observable.from(new String[]{"E", "C", "B", "G", "J", "O"});
observable1.concatMap(new Func1<String, Observable<Boolean>>() {
@Override
public Observable<Boolean> call(final String string) {
return observable2.contains(string);
}
}).zipWith(observable1, new Func2<Boolean, String, String>() {
@Override
public String call(final Boolean contains, final String string) {
return contains ? "" : string;
}
}).filter(new Func1<String, Boolean>() {
@Override
public Boolean call(final String string) {
return !TextUtils.isEmpty(string);
}
}).subscribe(new Action1<String>() {
@Override
public void call(final String string) {
Log.d("observable:", string);
}
});
在收到ob2的所有项目之前,无法计算操作的输出,因为在知道所有属于ob2的项目之前,无法确定ob1中的项目是否将包含在ob2中。 因此,您必须等待ob2完成,然后才能从ob1过滤项目。
使用RxJava2的可能解决方案如下。
Observable<String> ob1 = Observable.fromArray("A", "B", "C", "D");
Observable<String> ob2 = Observable.fromArray("E", "C", "B", "G", "J", "O");
Observable.combineLatest(ob2.toList().toObservable(), ob1, (list, value) -> list.contains(value) ? "" : value)
.filter(value -> !TextUtils.isEmpty(value))
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(value -> Log.d("foo", "Value: " + value));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.