如何使用 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()
}

我没有对此进行测试,但我认为您可以使用 flatmapreduce(或 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") }
    )

我最终选择了这个解决方案,它允许我访问 ListPost 个对象。谢谢指点。

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()
    }