Android Rxjava zip操作符通过检查第一个可观察到的数据来过滤第二个可观察到的数据

Android Rxjava zip操作符通过检查第一个可观察到的数据来过滤第二个可观察到的数据,android,filter,rx-java,rx-android,Android,Filter,Rx Java,Rx Android,我正在使用.zip操作符组合2个API调用 我想要什么 我想根据1st Observable中的一些id从2nd Observable中获得过滤值 例如 1st Observable返回数据,如(样本数据) Second Observable返回如下数据: "data": [ { "cat_id": "1", "category_name": "Wedding Venues", "status": "1",

我正在使用
.zip
操作符组合2个
API调用

我想要什么

我想根据
1st Observable
中的一些
id
2nd Observable
中获得过滤值

例如

1st Observable
返回数据,如(样本数据)

Second Observable
返回如下数据:

"data": [
        {
            "cat_id": "1",
            "category_name": "Wedding Venues",
            "status": "1",
            "order_id": "1",
            "category_type_id": "1"
        },
我想过滤我的第二个可观察数据,只返回与第一个可观察数据的类别\u类型\u id匹配的值

我的代码

Observable obsService = retrofitService.loadService(getSharedPref().getVendorId());
Observable obsCategory = retrofitService.loadCategory();

Observable<ServiceAndCategory> obsCombined = Observable.zip(obsService.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()), obsCategory.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()), new Func2<ServiceModel, CategoryModel, ServiceAndCategory>() {
            @Override
            public ServiceAndCategory call(ServiceModel serviceModel, CategoryModel categoryModel) {
                return new ServiceAndCategory(serviceModel, categoryModel);
            }
        });
        obsCombined.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io());

        obsCombined.subscribe(new Subscriber<ServiceAndCategory>() {
            @Override
            public void onCompleted() {


            }

            @Override
            public void onError(Throwable e) {
                if (e instanceof UnknownHostException || e instanceof ConnectException) {
                    mPresenter.onNetworkError();
                } else if (e instanceof SocketTimeoutException) {
                    mPresenter.onTimeOutError();
                } else {
                    mPresenter.onServerError();
                }
            }

            @Override
            public void onNext(ServiceAndCategory model) {

                mPresenter.onSuccess(model);
            }
        });
obbservice=reformationservice.loadService(getSharedRef().getVendorId());
Observable obsCategory=service.loadCategory();
Observable obsCombined=Observable.zip(obsService.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()),obsCategory.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()),new Func2(){
@凌驾
公共服务和类别调用(ServiceModel ServiceModel,CategoryModel CategoryModel){
返回新的ServiceAndCategory(serviceModel、categoryModel);
}
});
obsCombined.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io());
obsCombined.subscribe(新订户(){
@凌驾
未完成的公共无效(){
}
@凌驾
公共无效申报人(可丢弃的e){
if(未知后异常的e实例| |连接异常的e实例){
mPresenter.onNetworkError();
}else if(SocketTimeoutException的实例){
mPresenter.onTimeOutError();
}否则{
mPresenter.onServerError();
}
}
@凌驾
public void onNext(服务和类别模型){
mPresenter.onSuccess(模型);
}
});
编辑

基本上,我想应用以下逻辑

this.categoryList = combinedModel.categoryModel.getData();
        serviceList = combinedModel.serviceModel.getData().getCategories();

        for (int i = 0; i < serviceList.size(); i++) {

            for (int j = 0; j < categoryList.size(); j++) {

                if (!serviceList.get(i).getCategoryTypeId().equals(categoryList.get(j).getCategoryTypeId())) {

                    categoryList.remove(j);

                }

            }

        }
this.categoryList=combinedModel.categoryModel.getData();
serviceList=combinedModel.serviceModel.getData().getCategories();
对于(int i=0;i
您可以使用地图和列表,通过反应式方法应用此过滤,首先将所有类别收集到地图,将所有服务收集到列表,将它们压缩在一起,然后根据类别地图过滤服务列表:

Observable<HashMap<Integer, CategoryData>> categoriesMapObservable =
        obsCategory
                .flatMapIterable(CategoryModel::getData)
                .reduce(new HashMap<>(),
                        (map, categoryData) -> {
                            map.put(categoryData.getCategoryTypeId(), categoryData);
                            return map;
                        }
                );

Observable<List<ServiceData>> serviceListObservable = obsService
        .map(ServiceModel::getData);

Observable obsCombined =
        Observable.zip(
                categoriesMapObservable
                        .subscribeOn(Schedulers.io()),
                serviceListObservable
                        .subscribeOn(Schedulers.io()),
                Pair::new
        )
                .flatMap(hashMapListPair -> {
                    HashMap<Integer, CategoryData> categoriesMap = hashMapListPair.first;
                    return Observable.from(hashMapListPair.second)
                            .filter(serviceData -> categoriesMap.containsKey(serviceData.getCategoryTypeId()))
                                .toList();
                    }, (hashMapListPair, serviceDataList) -> new Pair<>(hashMapListPair.first.values(), serviceDataList));
可观察的类别mapobservable=
障碍类别
.FlatMapiteTable(CategoryModel::getData)
.reduce(新的HashMap(),
(地图,分类数据)->{
put(categoryData.getCategoryTypeId(),categoryData);
返回图;
}
);
可观察的服务ListObservable=obbservice
.map(ServiceModel::getData);
可观测障碍物=
可观察的.zip(
可观测的分类
.subscribeOn(Schedulers.io()),
服务列表可观察
.subscribeOn(Schedulers.io()),
配对::新
)
.flatMap(hashMapListPair->{
HashMap categoriesMap=hashMapListPair.first;
返回Observable.from(hashMapListPair.second)
.filter(serviceData->categoriesMap.containsKey(serviceData.getCategoryTypeId()))
.toList();
},(hashMapListPair,serviceDataList)->新对(hashMapListPair.first.values(),serviceDataList));
输出结果取决于您,这里我在末尾应用了一个选择器
flatMap()
,它将创建一对
CategoryData
集合和一个过滤后的
ServiceData
,您当然可以创建任何需要的自定义对象

我不确定您是否从中获益匪浅,从复杂性的角度来看,它似乎更有效,假设HashMap是O(1),其中类别是N,服务是m,这里有N+m(N构造映射,m迭代列表并查询映射),而您的天真实现将是N x m

至于代码复杂性,我不确定它是否值得,您可以在zip末尾应用您的逻辑进行过滤,或者使用一些可能更有效地进行过滤的库


p.S
observer(AndroidSchedulers.mainThread(
)是不必要的,所以我删除了它。

避免observer(AndroidSchedulers.mainThread()给了我在其他线程上更新视图的错误,这就是为什么我包括在内。谢谢你的回答。我没有很好地解释我自己,我从flatmap Observable中删除了它,你需要一个observeOn(AndroidSchedulers.mainThread)在订阅获取主线程通知之前是的。
Observable<HashMap<Integer, CategoryData>> categoriesMapObservable =
        obsCategory
                .flatMapIterable(CategoryModel::getData)
                .reduce(new HashMap<>(),
                        (map, categoryData) -> {
                            map.put(categoryData.getCategoryTypeId(), categoryData);
                            return map;
                        }
                );

Observable<List<ServiceData>> serviceListObservable = obsService
        .map(ServiceModel::getData);

Observable obsCombined =
        Observable.zip(
                categoriesMapObservable
                        .subscribeOn(Schedulers.io()),
                serviceListObservable
                        .subscribeOn(Schedulers.io()),
                Pair::new
        )
                .flatMap(hashMapListPair -> {
                    HashMap<Integer, CategoryData> categoriesMap = hashMapListPair.first;
                    return Observable.from(hashMapListPair.second)
                            .filter(serviceData -> categoriesMap.containsKey(serviceData.getCategoryTypeId()))
                                .toList();
                    }, (hashMapListPair, serviceDataList) -> new Pair<>(hashMapListPair.first.values(), serviceDataList));