RXJava2 | Android:过滤arrayList并跟踪过滤器
问题描述:
场景:RXJava 2. Android。RXJava2 | Android:过滤arrayList并跟踪过滤器
想象一下,你有从迭代可观察到的,像这样:Observable.fromIterable(arrayList<Something>)
,你需要做两件事情吧:
筛选的项目。
知道一个项目是否被过滤出来(又名:过滤函数返回false至少一次)。
这是一个类似观察到的(极度简化是相关的):
final ArrayList<Something> someArrayList = getTheArrayList();
Observable
.fromIterable(someArrayList)
.subscribeOn(Schedulers.computation())
.filter(new AppendOnlyLinkedArrayList.NonThrowingPredicate<Something>() {
@Override
public boolean test(final Something something) {
return something.isValid();
}
})
.toList()
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(new Consumer<List<Something>>() {
@Override
public void accept(@NonNull final List<Something> somethings)
throws Exception {
// How can I tell if the filter above returned false
// at least once?
}
})
.subscribe();
为了回答上述问题,一种选择是将原始someArrayList
比较somethings
。如果它们不同,那么发生了一些事情。但是这意味着列表必须以相同的顺序具有相同的项目,如果Something
是一个复杂的对象,必须实现一个equals,这可能会成为问题。
B计划,这是我现在用的,我不喜欢的是保持一个“布尔阵”外观察到,像这样:
final boolean[] hasInvalidData = new boolean[1];
,然后在.filter
我可以做:
final isValid = something.isValid();
if (!isValid) {
hasInvalidData[0] = true;
}
return isValid;
和成功,我可以简单地这样做:
if (hasInvalidData[0]) {
// Something has been filtered
}
问题是:有没有更好的方法?
UPDATE:
我迄今所做的仅仅是比较originalList.size()
与finalEmitedList.size()
。如果它们不同,那意味着我的过滤器“过滤”了一些东西。
答
我读它的方式,闻起来像是XY problem。如果您不需要跟踪的元素,你只需要计算,直到找到一个元素,一切都变得容易得多:
Observable
.fromIterable(someArrayList)
.subscribeOn(Schedulers.computation())
.map(something -> something.isValid())
.filter(bool -> bool)
.first(false);
如果你确实需要的元素列表:
Observable<Something> source = Observable
.fromIterable(someArrayList)
.subscribeOn(Schedulers.computation())
.publish()
.autoConnect(2);
source
.map(something -> something.isValid())
.reduce(false, (a,b) -> a | b)
.zipWith(source.toList(), (flag, list) -> {
// do your stuff
})
.subscribe();
答
不知道它的工作原理,但Observable.sequenceEqual可以工作:
ArrayList<Object> list = ...
Predicate myFilter = ...
Observable<Object> observable = Observable.fromIterable(list);
Observable.sequenceEqual(observable, observable.filter(myFilter))
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(@NonNull Boolean changed) throws Exception {
// result here
}
});
它可以是一个XY问题(我意识到这一点,感谢您刷新我的记忆),但是...我需要跟踪列表(最后,也就是过滤后)。我只需要知道一个项目是否被过滤(任何)。我所做的基本上是,计算最后的项目数量并比较它们是否相同。由于唯一的操作是删除(过滤器),最终列表将包含更少项目的唯一方法是过滤器返回false。比布尔事件好得多,但也许有更好的办法。 –
也许你想将所有'Something's转换为'Pair'。 –
请注意,由于您没有flatMap或类似地图,因此您将按顺序计算所有内容。 –