任何可以 FlatMap 和 return 输出的 Rx 运算符

Any Rx operator which could FlatMap and return both the output

我想知道是否有适合我的用例的 RxJava 运算符。我有以下两种方法。这些是改装接口。

fun getSources(): Single<Sources>
fun getTopHeadlines(sourceCsv: String): Single<TopHeadlines>

目前我正在做这个

getSources()
    .map { sources -> 
        // convert the sources list to a csv of string 
    }
    .flatMap { sourcesCsv
        getTopHeadlines(sourcesCsv)
    }
    .subsribe {topHeadlines, error -> }

如果我的 objective 是为了获得头条新闻,这很好用。但是我在订阅它的同时试图获得的是消息来源和头条新闻?有没有我不知道的操作员,或者有没有其他方法可以做到这一点?

您可以使用 zip() 方法来完成此操作。 zip 等待这两个项目然后发出所需的值。你可以这样使用它

getSources()
    .map { sources -> 
        // convert the sources list to a csv of string 
    }
    .flatMap { sourcesCsv ->
        Single.zip(
            Single.just(sourcesCsv),
            getTopHeadlines(sourcesCsv),
            BiFunction { t1, t2 -> Pair(t1, t2) }
        )
    }
    

然后当你订阅这个时你有两个值作为一对。你可以为它做一个扩展功能,让你的生活更轻松:

fun <T, V> Single<T>.zipWithValue(value: V) = Single.zip(
    Single.just(value),
    this,
    { t1, t2 -> Pair(t1, t2) }
)

在你的 flatMap 里面你可以做 getTopHeadlines(sourcesCsv).zipWithValue(sourcesCsv)。对于 Maybe 也可以这样做,对于 Flowabale 你可以使用 combineLatest() 方法。


作为 mohsens 回答的补充:

你不需要压缩它。只需在 flatMap 中使用另一个 map 运算符并将两个值组合成 Pair,就像我在这个示例中所做的那样:

import io.reactivex.rxjava3.core.Single
import org.junit.jupiter.api.Test

class So65640603 {
    @Test
    fun `65640603`() {
        getSources()
            .flatMap { source -> getTopHeadlines(source).map { headLines -> source to headLines } }
            .test()
            .assertValue("v1" to 42)
    }
}

fun getSources(): Single<String> {
    return Single.just("v1")
}

fun getTopHeadlines(sourceCsv: String): Single<Int> {
    return Single.just(42)
}