0

假设我有一个数字列表和 observable 的来源,它可以评估该列表中的每个数字。(需要使用以下方法。它们是我必须使用的 API 的一部分)

fun getNumberListSource() : Observable<List<Int>> {...}
fun getOddChecker(value: Int): Observable<Boolean> {...}

假设源看起来像这样:

class NumberSource {

    private val source = BehaviorSubject.create<List<Int>>()

    fun getNumberListSource(): Observable<List<Int>> = source.doOnNext { println("doOnNext :)") }

    fun start(){
        Thread {
            Thread.sleep(1000)
            source.onNext(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
            Thread.sleep(1000)
            source.onNext(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
            Thread.sleep(1000)

            source.onComplete()
        }.start()

    }
}

有趣的 getOddChecker(i: Int) : Observable = Observable.just(i%2== 0)

在流的末尾,我需要有奇数列表。所以我做了那个代码:

fun main() {
    val numberSource = NumberSource()
    numberSource.start()
    println("== started ==")

    numberSource.getNumberListSource()
        .flatMap {
            Observable.fromIterable(it)
                .flatMap (
                    {getOddChecker(it)},
                    {a, b -> a to b}
                )
                .filter { it.second }
                .map { it.first }
                .toList()
                .toObservable()
        }
        .subscribe({ println("onNext: $it")},{},{ print("action:onComplete")})

}

上面代码的输出:

== started == 
doOnNext :) 
onNext: [2, 4, 6, 8, 10, 12] 
doOnNext :) 
onNext: [2, 4, 6, 8, 10, 12] 
action:onComplete

上面的代码做了我想要的,但我必须使用Pair类。那个部分

        .filter { it.second }
        .map { it.first }

似乎不太可读。那么是否有任何运营商女巫可以简化该代码?

4

1 回答 1

1

你可以把它简化成这样

   getNumberListSource()
           .flatMap { Observable.fromIterable(it)
                    .flatMap { item -> getOddChecker(item).filter {it}.map { item } }
                    .toList().toObservable()
            }
            .subscribe({ println("onNext: $it")},{},{ print("action:onComplete")})
于 2019-09-29T10:07:35.217 回答