RxSwift过滤器变量数组

deh*_*len 4 functional-programming ios swift rx-swift

您好我正在尝试了解RxSwift库以编写更好的功能代码.

目前我陷入了一个非常基本的问题.可以说我得到了这种类型的变量Variable<[CiteModel?]>:

var allCites: Variable<[CiteModel?]> = Variable([])
var shownCites: Variable<[CiteModel?]> = Variable([])
Run Code Online (Sandbox Code Playgroud)

现在我想过滤allCites包含特定文本的数组中的所有引用并将它们添加到shownCites.

这是我试过,但它并没有编译,因为在我的过滤器块$0[CiteModel?] 不是 CiteModel?我所期望的那样.你能解释一下我做错了什么吗?

private func filterCitesByQuery(query: String) {
    self.shownCites = self.allCites.asObservable().filter {
        $0?.cite.containsString(query)
    }
}
Run Code Online (Sandbox Code Playgroud)

执行上述代码时出错:

Cannot assign value of type 'Observable<[CiteModel?]>' (aka 'Observable<Array<Optional<CiteModel>>>') to type 'Variable<[CiteModel?]>' (aka 'Variable<Array<Optional<CiteModel>>>')
Run Code Online (Sandbox Code Playgroud)

tom*_*ahh 9

map序列的每个值执行操作.当应用于mapa时Observable<T>,mapT作为参数接收到其块.

在的情况下Variable<[CiteModel?]>,Observable序列因此T == [CiteModel?].

因为我们真的想要过滤一个数组[CiteModel?],你可以改变filterCitesByQueryto 的定义

private func filterCitesByQuery(query: String) {
    // bag probably needs to be reset here
    allCites.asObservable()
        .map { // map: apply a transformation to $0
        // The desired transformation of $0 is to remove cite that do not contain query 
        $0.filter { $0.cite.containsString(query) }
    }
    .bindTo(shownCites)
    .addDisposableTo(bag)
}
Run Code Online (Sandbox Code Playgroud)

但是这个片段仍然是次优的,因为它需要订阅allCites,我们并不真的想要观察它的变化.

一个更好的实施将是

var allCites: Variable<[CiteModel?]> = Variable([])
var searchQuery: Variable<String> = Variable("")
var shownCites: Observable<[CiteModel?]> = Observable .combineLatest(allCites.asObservable(), searchQuery.asObservable()) {
    allCites, query in
    return allCites.map { cites in cites.filter { $0.cite.containsString(query) } }
}

private func filterCitesByQuery(query: String) {
    searchQuery.value = query
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么 ?

combineLatest采用的最后2个已知值allCitessearchQuery.当其中任何一个发生更改时,都会执行该块.我们现在可以订阅shownCites并在每次源可观察的更改时获得更新的值.