使用flatMap和filter过滤observables是否正确?

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

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

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

  Observable categoryObservable = service.getCategoryPayload(); // use flatMap to transform the Observable into multiple mSubscription.add( categoryObservable.flatMap(new Func1<CategoryPayload, Observable>(){ public Observable call(CategoryPayload categoryPayload){ return Observable.from(categoryPayload.categories); } }).filter(new Func1(){ public Boolean call(Category category){ return category.id != SOME_BANNED_CATEGORY_ID; } }).toList()) .subscribe(mObserver); 

请原谅编造的代码。 我真的只是试图了解是否正确使用RX来平展我的可观察性,然后按照我上面的方式进行过滤。

我没有看到使用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) ); 

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

你可以使用Guava的集合过滤函数,或者Kotlin内置的Iterables函数(需要在Kotlin中重写),或者Xtend相当于Kotlin(需要在Xtend中重写),或者使用for循环写入手动variablesJava的。

总的来说,你可以通过Observable .map进行映射,并通过List进行过滤。