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

时间:2015-05-21 04:01:51

标签: java android reactive-programming rx-java rx-android

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

:after

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

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
}

请原谅人为的代码。我真的只是试图理解是否正确使用RX来展平我的observable然后按照我上面的方式过滤它。

2 个答案:

答案 0 :(得分: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)
);

答案 1 :(得分:1)

您正在使用Rx.Observable过滤器方法来过滤List。这是一种反模式,因为列表是Iterables,它是Observable的双重符号。因此,您真正想要的是列表的过滤器函数,而不是将Iterable转换为Observable。

你既可以使用Guava的过滤功能进行收藏,也可以使用Kotlin的Iterables内置功能(需要在Kotlin中重写),或者Xtend等同于Kotlin的功能。 (需要在Xtend中重写),或者用Java编写手动变异(带for for循环)。

总体而言,您.map超过Observable<CategoryPayload>并在地图内部对List<Category>进行过滤。