如何使用 RxJava 2 将单个 <List<List<T>>> 合并到列表<T> 中?
How Can I Merge a Single<List<List<T>>> Into a List<T> with RxJava 2?
我想要做的是点击一个端点来获取用户列表,即 returns Single<List<User>>
。接下来,我想抓住前三个用户并点击另一个端点以获取他们所有的帖子 Single<List<Post>>
。最后,我想显示一个 Toast
,前 3 个用户的帖子总数 。
我已经能够使用 Kotlin 中提供的 flatten()
函数来实现它。但是,我想知道如何只使用 RxJava 2 来做到这一点。这可能吗?谢谢。
...
getPostsForFirstThreeUsers()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ posts -> toast("There are: ${posts.flatten().size} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
fun getFirstThreeUsers(): Flowable<User> {
return getAllUsers()
.flattenAsFlowable { users -> users }
.doOnNext { Timber.i("a user: ${it.username}") }
.take(3)
}
fun getPostsForFirstThreeUsers(): Single<List<List<Post>>> {
return getFirstThreeUsers()
.flatMapSingle { api.getUsersPosts(it.id) }
.doOnNext { Timber.i("number of posts: ${it.size}") }
.toList()
}
我没有对此进行测试,但我认为您可以使用 flatmap
和 reduce
(或 collect
)来执行此操作。可能是这样的:
getAllUsers()
.take(3)
.flatMap { api.getUsersPosts(it.id) }
.map { it.size }
.reduce(0) { acc, e -> acc + e }
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ posts -> toast("There are: ${posts.flatten().size} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
由于您只查找帖子总数,因此您可以 flatmap
将列表添加到信息流,然后 count
。平面映射不保证顺序,而是将列表的列表扁平化为单个流。
getPostsForFirstThreeUsers()
.subscribeOn(Schedulers.io())
.flatmapObservable(Observable::fromIterable)
.flatmap(Observable::fromIterable)
.count()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ count -> toast("There are: ${count} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
我最终选择了这个解决方案,它允许我访问 List
个 Post
个对象。谢谢指点。
fun getPostsForFirstThreeUsers(): Single<MutableList<Post>> {
return getFirstThreeUsers()
.flatMapSingle { api.getUsersPosts(it.id) }
.doOnNext { Timber.i("number of posts: ${it.size}") }
.flatMapIterable { it }
.doOnNext { Timber.i("the post: $it") }
.toList()
}
我想要做的是点击一个端点来获取用户列表,即 returns Single<List<User>>
。接下来,我想抓住前三个用户并点击另一个端点以获取他们所有的帖子 Single<List<Post>>
。最后,我想显示一个 Toast
,前 3 个用户的帖子总数 。
我已经能够使用 Kotlin 中提供的 flatten()
函数来实现它。但是,我想知道如何只使用 RxJava 2 来做到这一点。这可能吗?谢谢。
...
getPostsForFirstThreeUsers()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ posts -> toast("There are: ${posts.flatten().size} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
fun getFirstThreeUsers(): Flowable<User> {
return getAllUsers()
.flattenAsFlowable { users -> users }
.doOnNext { Timber.i("a user: ${it.username}") }
.take(3)
}
fun getPostsForFirstThreeUsers(): Single<List<List<Post>>> {
return getFirstThreeUsers()
.flatMapSingle { api.getUsersPosts(it.id) }
.doOnNext { Timber.i("number of posts: ${it.size}") }
.toList()
}
我没有对此进行测试,但我认为您可以使用 flatmap
和 reduce
(或 collect
)来执行此操作。可能是这样的:
getAllUsers()
.take(3)
.flatMap { api.getUsersPosts(it.id) }
.map { it.size }
.reduce(0) { acc, e -> acc + e }
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ posts -> toast("There are: ${posts.flatten().size} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
由于您只查找帖子总数,因此您可以 flatmap
将列表添加到信息流,然后 count
。平面映射不保证顺序,而是将列表的列表扁平化为单个流。
getPostsForFirstThreeUsers()
.subscribeOn(Schedulers.io())
.flatmapObservable(Observable::fromIterable)
.flatmap(Observable::fromIterable)
.count()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ count -> toast("There are: ${count} posts") },
{ ex -> Timber.e(ex, "there was an error processing the request") }
)
我最终选择了这个解决方案,它允许我访问 List
个 Post
个对象。谢谢指点。
fun getPostsForFirstThreeUsers(): Single<MutableList<Post>> {
return getFirstThreeUsers()
.flatMapSingle { api.getUsersPosts(it.id) }
.doOnNext { Timber.i("number of posts: ${it.size}") }
.flatMapIterable { it }
.doOnNext { Timber.i("the post: $it") }
.toList()
}