Swift 合并:合并多个发布者并在其中任何一个发布者发出 `true` 时发出 `true`
Swift Combine: merge multiple publishers and emit `true` when any of them emits `true`
我正在尝试构建一个发布者,它在其他 5 个发布者中的任何一个发布者发出 true 时发出 true。我已经设法构建了一个工作版本,但使用 CombineLatest4 + CombineLatest 尤其是所有 [=12=].0 || [=12=].1 || [=12=].2 || [=12=].3
代码感觉非常恶心。
我试过 Merge5,但它似乎只是 returns 最后设置的值。
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 { [=11=].0 || [=11=].1 || [=11=].2 || [=11=].3 }
.combineLatest(test.$five)
.map { [=11=].0 || [=11=].1 }
anyTrue.sink {
print([=11=])
}
test.three = true
test.one = false
有没有更简洁、重复性更低的方法来做到这一点?
我编写了这个结合了 N 个发布者的自定义可变 combineLatest
函数。希望这就是您所需要的:
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(),
{ [=10=].combineLatest().map(reductionFunction).eraseToAnyPublisher() }
)
}
困难的部分是弄清楚 reduce
的身份应该是什么。哪个发布者 x
满足所有 y
的 x.combineLatest(y).map(f) == y
? x
的一种解决方案是发布者发布一次 f
的身份。
用法:
let anyTrue = combineLatestN(
identity: false,
reductionFunction: { [=11=] || },
publishers: test.$one, test.$two, test.$three, test.$four, test.$five)
我正在尝试构建一个发布者,它在其他 5 个发布者中的任何一个发布者发出 true 时发出 true。我已经设法构建了一个工作版本,但使用 CombineLatest4 + CombineLatest 尤其是所有 [=12=].0 || [=12=].1 || [=12=].2 || [=12=].3
代码感觉非常恶心。
我试过 Merge5,但它似乎只是 returns 最后设置的值。
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 { [=11=].0 || [=11=].1 || [=11=].2 || [=11=].3 }
.combineLatest(test.$five)
.map { [=11=].0 || [=11=].1 }
anyTrue.sink {
print([=11=])
}
test.three = true
test.one = false
有没有更简洁、重复性更低的方法来做到这一点?
我编写了这个结合了 N 个发布者的自定义可变 combineLatest
函数。希望这就是您所需要的:
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(),
{ [=10=].combineLatest().map(reductionFunction).eraseToAnyPublisher() }
)
}
困难的部分是弄清楚 reduce
的身份应该是什么。哪个发布者 x
满足所有 y
的 x.combineLatest(y).map(f) == y
? x
的一种解决方案是发布者发布一次 f
的身份。
用法:
let anyTrue = combineLatestN(
identity: false,
reductionFunction: { [=11=] || },
publishers: test.$one, test.$two, test.$three, test.$four, test.$five)