簡體   English   中英

RxJava比較兩個observable中的不同項(java 7)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM