嗨,我正在尝试了解 RxSwift 库以编写更好的功能性代码。

目前我被困在一个非常基本的问题上。假设我得到了 Variable<[CiteModel?]> 类型的变量:

var allCites: Variable<[CiteModel?]> = Variable([])
var shownCites: Variable<[CiteModel?]> = Variable([])

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

这是我尝试过的,但它无法编译,因为在我的过滤器块中 $0[CiteModel?] 而不是 CiteModel? 我所期望的。你能向我解释我做错了什么吗?
private func filterCitesByQuery(query: String) {
    self.shownCites = self.allCites.asObservable().filter {
        $0?.cite.containsString(query)
    }
}

执行上述代码时出现 错误:
Cannot assign value of type 'Observable<[CiteModel?]>' (aka 'Observable<Array<Optional<CiteModel>>>') to type 'Variable<[CiteModel?]>' (aka 'Variable<Array<Optional<CiteModel>>>')

最佳答案

map 序列 的每个值执行操作。将 map 应用于 Observable<T> 时,map 将接收 T 作为其块的参数。

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

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

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

但是这个片段仍然是次优的,因为它需要订阅 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
}

这里发生了什么 ?
combineLatestallCitessearchQuery 的最后两个已知值。当其中任何一个发生变化时,就会执行该块。我们现在可以订阅 shownCites 并且每次源 observable 更改时都会获得更新的值。

关于ios - RxSwift 过滤器变量数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36190967/

10-09 02:46