2

使用一个人为的例子来说明我的问题,我有一个复合对象类型的 Observable:

Observable<Category>

public class CategoryPayload {
     public List<Category> categories;
     // other meta data and getters
}
public class Category {
     public Integer id;
     // other meta data and getters
}

我需要根据 id 过滤掉某些类别,所以我最终会做类似的事情:

    Observable<CategoryPayload> categoryObservable = service.getCategoryPayload();
    // use flatMap to transform the Observable into multiple
mSubscription.add(
    categoryObservable.flatMap(new Func1<CategoryPayload, Observable<Category>>(){

         public Observable<Category> call(CategoryPayload categoryPayload){
              return Observable.from(categoryPayload.categories);
         }
    }).filter(new Func1<Category, Boolean>(){
        public Boolean call(Category category){
             return category.id != SOME_BANNED_CATEGORY_ID;
        }

     }).toList())
     .subscribe(mObserver);

请原谅人为的代码。我真的只是想了解是否正确使用 RX 来展平我的 observable 然后以我上面所做的方式对其进行过滤。

4

2 回答 2

3

您正在使用 Rx.Observable 过滤器方法来过滤列表。这是一种反模式,因为 List 是 Iterable,它是 Observable 的对偶。因此,您真正想要的是列表的过滤器功能,而不是将 Iterable 转换为 Observable。

您可以将 Guava 的过滤器函数用于集合,或者 Kotlin 的内置函数用于 Iterables(需要在 Kotlin 中重写),或者 Xtend 等效于 Kotlin 的(需要在 Xtend 中重写),或者在爪哇。

总体而言,您将.mapObservable<CategoryPayload>地图内部和内部进行过滤List<Category>

于 2015-05-21T06:33:49.903 回答
3

我认为使用 RxJava 没有任何问题。如果您期望一个结果,getCategoryPayload()或者您不关心多个类别列表是否进入同一个聚合列表,那么您的示例是可以的。

mSubscriptions.add(
    service.getCategoryPayload()
    .flatMapIterable(p -> p.categories)
    .filter(c -> c.id != SOME_BANNED_CATEGORY_ID)
    .toList()
    .subscribe(mObserver)
);

否则,如果您想保持有效负载完整但修剪类别,您可以使用任何流畅的 Iterable API(Guava、IxJava):

mSubscriptions.add(
    service.getCategoryPayload()
    .map(p -> {
        Ix.from(p.categories).filter(c -> c.id == SOME_BANNED_CATEGORY_ID).removeAll();
        return p.categories; // or just return p;
    })
    .subscribe(mObserver)
);
于 2015-05-21T07:31:36.280 回答