场景:RXJava 2. Android。
想象一下你有一个可迭代的Observable,如:Observable.fromIterable(arrayList<Something>)
,你需要做两件事:
过滤项目。
知道某个项目是否被过滤掉了(a.k.a:过滤器函数至少返回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
是一个复杂的对象,则必须实现等于,这可能是一个问题。
我正在使用并且我不喜欢的计划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
}
问题是:有更好的方法吗?
更新:
到目前为止,我所做的只是将originalList.size()
与finalEmitedList.size()
进行比较。如果它们不同,那意味着我的过滤器“过滤”了一些东西。
答案 0 :(得分:2)
我读它的方式,闻起来像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();
答案 1 :(得分:1)
不确定是否有效,但 Observable.sequenceEqual 可行:
{!! $stok->name !!}