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 满足所有 yx.combineLatest(y).map(f) == yx 的一种解决方案是发布者发布一次 f 的身份。

用法:

let anyTrue = combineLatestN(
                identity: false, 
                reductionFunction: { [=11=] ||  }, 
                publishers: test.$one, test.$two, test.$three, test.$four, test.$five)