考虑以下集合和对象:
Observable.from(users); // Where users = List<User> and each user has a userId
Observable.just(location); // Where location has id, userId, coordinates
我想做的是遍历用户列表,并在第一次遇到 location.userId.equals(user.userId);
时在数据库中查询,返回一个组合对象。如果userId
s 不匹配移动到下一个用户。并在找到 1 个匹配项后终止循环。
我如何使用 RxJava 实现这一点?
我最初想使用:
Observable.zip(Observable.from(users), Observable.just(location), new Func2<User, Location, UserLocation>() { ... });`
有没有人有更好的选择?
编辑:
我想也许我可以用一个简单的解决方案来解决这个问题,但好吧,我会更清楚地解释一切。
所以一旦我有了location.userId
, 和 user.userId
我还需要查询一个将返回 Observable<Boolean>
的数据库表明它在我们的数据库中是否也是如此。如果该条件匹配,那么我将返回一个组合对象。
所以整个流程是这样的:
for each user in Users {
checkIfAlreadyExistsInDatabase(user.userId, location.userId) // Returns Observable<Boolean>
// If exists in db AND user.userId == location.userId return combined object and terminate the loop
}
这以前是在没有 RxJava
的情况下同步完成的我转换了方法 checkIfAlreadyExistsInDatabase
接收并使用 Schedulers.io
在后台线程上 ping 数据库以使应用程序响应更快。当我不得不遍历一组用户并将 id 与 Location 匹配并且还 ping 我的数据库时,问题就出现了。
为了让我调用方法 checkIfAlreadyExistsInDatabase
我需要捕获 user.userId
为此,我需要遍历 users
并使用 location.userId
进行过滤.
所以:
- 遍历用户
- 如果 user.userId 匹配 location.userId 检查它是否存在于数据库中
- 如果存在于数据库中则返回一个组合对象
- 一旦找到 1 个匹配项就终止循环
最佳答案
zip
函数的问题在于它从左侧 Observable
发出一项,从右侧 Observable
发出一项。因此,您提供的功能只会对第一个用户执行。但这是一个很好的方向。只需重复第二个 Observable
适当的次数 - 使用 repeat
。如果您真的想使用 RxJava 执行此操作,建议使用以下方法:
Observable.zip(Observable.from(userList),
Observable.just(location).repeat(userList.size()),
new Func2<User, Location, User>() {
@Override
public User call(User user, Location location) {
return user.id.equals(location.id) ? user : null;
}
})
.filter(new Func1<User, Boolean>() {
@Override
public Boolean call(User user) {
return user != null;
}
});
然而,这种方法 null
是通过 Observable
流传递的,不推荐这样做。
我不会用 RxJava 来做,只用传统 Java 的 Iterator
。
关于android - 仅在条件匹配时返回组合的 Observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41218260/