swift - Swift Combine:合并多个发布者并在其中任何一个发出“真”时发出“真”
问题描述
我正在尝试建立一个发布者,当其他 5 个发布者中的任何一个发布为 true 时,该发布者会发出 true。我已经设法构建了一个工作版本,但使用 CombineLatest4 + CombineLatest 尤其是所有$0.0 || $0.1 || $0.2 || $0.3
代码感觉非常恶心。
我已经尝试过 Merge5,但这只是返回似乎设置的最后一个值的值。
import Foundation
import Combine
class Test {
@Published var one = false
@Published var two = false
@Published var three = false
@Published var four = false
@Published var five = false
}
let test = Test()
var anyTrue = Publishers.CombineLatest4(test.$one, test.$two, test.$three, test.$four)
.map { $0.0 || $0.1 || $0.2 || $0.3 }
.combineLatest(test.$five)
.map { $0.0 || $0.1 }
anyTrue.sink {
print($0)
}
test.three = true
test.one = false
有没有更清洁、重复性更低的方法来做到这一点?
解决方案
我编写了这个combineLatest
结合了 N 个发布者的自定义可变参数函数。希望这是您需要的:
func combineLatestN<P, T, E>(identity: T, reductionFunction: @escaping (T, T) -> T, publishers: P...) -> AnyPublisher<T, E>
where P: Publisher, P.Output == T, P.Failure == E {
publishers.reduce(
Publishers.Sequence<[T], E>(sequence: [identity]).eraseToAnyPublisher(),
{ $0.combineLatest($1).map(reductionFunction).eraseToAnyPublisher() }
)
}
困难的部分是弄清楚reduce
应该是什么身份。什么出版商x
能满足x.combineLatest(y).map(f) == y
所有人y
?一种解决方案x
是发布f
一次身份的发布者。
用法:
let anyTrue = combineLatestN(
identity: false,
reductionFunction: { $0 || $1 },
publishers: test.$one, test.$two, test.$three, test.$four, test.$five)
推荐阅读
- ruby-on-rails - 如何在 Rails 中使消息仅由两个用户(私人消息)阅读?
- python - Python Pandas 数据以日期格式输出到 excel 的问题
- r - 在闪亮的r中计算输入数据列中唯一向量的数量
- node.js - 为什么我的 GraphQL 订阅在本地服务器上运行,但在实时服务器上部署时却不行
- python - Python正则表达式,否定字符串之间的一组字符
- javascript - 如何在 jquery .html() 方法中设置数组或倍数 var?
- html - 我希望引导程序在一个扩展另一个将关闭时崩溃
- mongodb - MongoExpress 没有从 .env 文件中读取登录名/密码
- python - 链接响应是 401,但它在前一段时间工作,然后工作 python
- javascript - Firebase 模拟器对本地 FireStore 的请求不成功