Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用rxSwift进行压缩、合并或压缩,而不覆盖以前的数据?_Ios_Swift_Observable_Concat_Rx Swift - Fatal编程技术网

Ios 如何使用rxSwift进行压缩、合并或压缩,而不覆盖以前的数据?

Ios 如何使用rxSwift进行压缩、合并或压缩,而不覆盖以前的数据?,ios,swift,observable,concat,rx-swift,Ios,Swift,Observable,Concat,Rx Swift,我有三个Observable流,我想把它们合并成一个Observable 如果我使用Observable.zip(早餐、甜点、饼干).do(onNext:{[weak self]value in… 我得到([Recipe],[Recipe],[Recipe]) 如果我使用Observable.merge(早餐、甜点、饼干).do(onNext:{[weak self]value in… 我依次获得流,这意味着最后一个完成的流将覆盖前两个 如果我使用Observable.concat(早餐、甜点、

我有三个
Observable
流,我想把它们合并成一个
Observable

如果我使用
Observable.zip(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我得到
([Recipe],[Recipe],[Recipe])

如果我使用
Observable.merge(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我依次获得流,这意味着最后一个完成的流将覆盖前两个

如果我使用
Observable.concat(早餐、甜点、饼干).do(onNext:{[weak self]value in…
我的行为与
merge
类似

那么,如何将这三个流合并为一个流,而不让它们相互覆盖呢

为了更好地了解我要做的事情:

return Observable.merge(breakfast, cookies, dessert).do(onNext: { [weak self] value in
    self?.content.accept(value.compactMap { FavoritesCollectionViewCellViewModel(favorite: $0)})
})

我想
接受
所有组合流到
行为关系
,映射到
单元格
数据。
内容
中继随后被
绑定到
集合视图
。当观看
集合视图
时,使用
concat
我可以简单地看到第一个和第二个流,然后它们被重新播放与最后一个流进行了比较。

好的,我不知道这是否是解决问题的最漂亮的方法,但我使用了
zip
,然后在
compactMap
中将数组相互添加

return Observable.zip(breakfast, dessert, cookies)
    .compactMap { $0.0 + $0.1 + $0.2 }
    .do(onNext: { [weak self] value in
        self?.content.accept(value.compactMap { FavoritesCollectionViewCellViewModel(favorite: $0)})
})

您可能不知道,但是CombineTest(和zip)有一个用于操作输入的最终参数。因此,您可以执行以下操作:

let allRecipes = Observable.combineLatest(breakfast, dessert, cookies) { $0 + $1 + $2 }
这相当于:

Observable.combineLatest(breakfast, dessert, cookies)
        .map { $0.0 + $0.1 + $0.2 }
这与您最终得到的基本相同,只是您使用了
zip
而不是
combinelateest

使用
zip
假设所有三个可观测对象将发射完全相同数量的元素。通过使用CombineTest,您假设每个可观测对象至少发射一个元素,但它们不必发射相同数量的元素

如果您想避免这种假设,那么在每个源代码中添加一个
.startWith

Observable.combineLatest(
    breakfast.startWith([]),
    dessert.startWith([]),
    cookies.startWith([])
) { $0 + $1 + $2 }
通过上面的方法,只要有一个可观测的源发射,你就会在输出中得到一些东西,而其他源每次发射时,你就会得到另一个更大的阵列


请注意,在以上所有内容中(包括您的答案)任何一个源观测值中的错误都会导致整个事件出错。如果要避免这种情况,您必须捕获每个源观测值中的错误。该代码的确切外观取决于您希望如何处理这些错误。

这是一个非常好的解释,非常感谢@Daniel T。
Observable.combineLatest(
    breakfast.startWith([]),
    dessert.startWith([]),
    cookies.startWith([])
) { $0 + $1 + $2 }