RxSwift 将可观察对象数组与对象数组结合

Posted

技术标签:

【中文标题】RxSwift 将可观察对象数组与对象数组结合【英文标题】:RxSwift Combine Array of observables with array of objects 【发布时间】:2020-04-07 03:05:50 【问题描述】:

我正在尝试使用 RxSwift 从 Firebase 获取数据。我正在使用this 执行 API 调用。

所以我的数据库看起来像这样: Category 集合(它具有属性:title、about 等)在其中包含另一个名为 Manifests 的集合。要获得 Manifests,我需要使用 Category 集合的documentId。所以这是两个不同的 API 调用,但我想合并结果

这就是我目前所拥有的:

    func fetchCategories() -> Observable<[ManifestCategory]> 
        let ref = self.db.collection(FirebaseCollection.manifestCategories.collectionPath)

        return ref.rx.getDocuments().map( snapshot in
            return snapshot.documents.map( doc in
                var category = ManifestCategory.init(JSON: doc.data())

                category?.documentId = doc.documentID

                return category
                ).compactMap( $0 )
        )
    

    func fetchManifests(categoryId: String) -> Observable<[Manifest]> 
        let ref = self.db.collection(FirebaseCollection.manifests(categoryId: categoryId).collectionPath)

        return ref.rx.getDocuments().map( snapshot in
            return snapshot.documents.map( doc in
                var manifest = Manifest.init(JSON: doc.data())

                manifest?.documentId = doc.documentID

                return manifest
            ).compactMap( $0 )
        )
    

有什么方法可以将 Manifests 数组放入 Category 对象中?

谢谢!

【问题讨论】:

【参考方案1】:

你应该试试这样的:

func fetchCategories() -> Observable<[ManifestCategory]> 
    let ref = self.db.collection(FirebaseCollection.manifestCategories.collectionPath)

    return ref.rx.getDocuments()
        .map  snapshot in
            return snapshot.documents
                .map  doc in
                    var category = ManifestCategory.init(JSON: doc.data())
                    category?.documentId = doc.documentID
                    return category
                
                .compactMap  $0 
        
        .flatMapLatest  [weak self] categories -> Observable<[ManifestCategory]> in
            guard let self = self else 
                return .empty()
            

            let observables = categories.map  category -> ([Manifest], String) in
                self.fetchManifests(categoryId: category.documentId)
                    .map  ($0, category.documentId) 
            

            return Observable.zip(observables)
                .map  tuple -> [ManifestCategory] in
                    tuple.compactMap  manifests, id in
                        if var category = categories.first(where:  $0.documentId == id ) 
                            category.manifests = manifests
                            return category
                        
                        return nil
                    
                
        

【讨论】:

以上是关于RxSwift 将可观察对象数组与对象数组结合的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift:结合不同类型的可观察对象和映射结果

淘汰赛将选择绑定到动态可观察数组

RxSwift:将可完成映射到单个可观察?

Rxswift 改变观察对象的值

如何在 RxSwift 中观察对象的属性?

RxSwift:返回一个带有错误的新可观察对象