首页 > 解决方案 > RxSwift - 如何连接可观察的集合

问题描述

我正在尝试将两个可观察的集合与concat()运算符连接起来,但是,它没有按预期工作。

我有两个可观察的:

let first = Observable<[Int]>.create { observer in
    observer.onNext([1, 2])
    observer.onCompleted()
    return Disposables.create()
}

let second = PublishSubject<[Int]>()

使用concat()

let items = Observable.concat([first, second])

items.subscribe(onNext: {
    print($0)
})

second.onNext([3, 4, 5])

输出:

[1, 2]
[3, 4, 5]

我想要的是:

[1, 2]
[1, 2, 3, 4, 5]

标签: swiftreactive-programmingrx-swift

解决方案


因此,您不仅想连接两个可观察对象,还想连接两个可观察对象产生的事件中的数组。你走得还不够远,无法得到你想要的。

想象一下,你有两个 Array<[Int]> 而不是两个 Observable<[Int]>。将两者连接起来(如在 arr1 + arr2 中)不会产生[[1, 2], [1, 2, 3, 4, 5]],而是会产生 [[1, 2], [3, 4, 5]]。您的 Observables 的行为方式相同。

要连接组合它们,您需要scan,如:

let items = Observable.concat([first, second])
    .scan([], accumulator: +)

这将产生两个事件:

[1, 2]
[1, 2, 3, 4, 5]

仅供参考,对于数组,我们没有扫描运算符,但我们可以用 reduce 来近似它。对于数组,它将是:

let arr1: Array<[Int]> = [[1, 2]]
let arr2: Array<[Int]> = [[3, 4, 5]]
let itemsArr = (arr1 + arr2).reduce([], { result, element in
    return result + [(result.last ?? []) + element]
})
print(itemsArr)

推荐阅读