具有超过 4 个值的 SwiftUI 和 CombineLatest

SwiftUI and CombineLatest with more than 4 values

我开始尝试使用 SwiftUI,但我遇到了需要 5 个滑块的最新组合的情况。我使用 CombineLatest4 使用 4 个滑块完成所有工作,然后意识到我需要另一个滑块,但没有 CombineLatest5.

感谢任何帮助。

澄清工作 4 滑块版本:

Publishers
    .CombineLatest4($slider1, $slider2, $slider3, $slider4)
    .debounce(for: 0.3, scheduler: DispatchQueue.main)
    .subscribe(subscriber)

CombineLatest2(CombineLatest3, CombineLatest2) 应该可以解决问题,不是吗?

您可以使用类似的东西:

extension Publisher {
public func combineLatest<P, Q, R, Y>(
    _ publisher1: P,
    _ publisher2: Q,
    _ publisher3: R,
    _ publisher4: Y) ->
    AnyPublisher<(Self.Output, P.Output, Q.Output, R.Output, Y.Output), Self.Failure> where
    P: Publisher,
    Q: Publisher,
    R: Publisher,
    Y: Publisher,
    Self.Failure == P.Failure,
    P.Failure == Q.Failure,
    Q.Failure == R.Failure,
    R.Failure == Y.Failure {
    Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4).map { tuple, publisher4Value in
        (tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
    }.eraseToAnyPublisher()
  }
}

并这样称呼它:

publisher1.combineLatest(publisher2, publisher3, publisher4, publisher5)

注意 - 从问题中提取的解决方案


好的,弄清楚语法,@Daniel-t 是对的。我只需要创建子发布者:

let paramsOne = Publishers
    .CombineLatest3($slider1, $slider2, $slider3)
        
let paramsTwo = Publishers
    .CombineLatest($slider4, $slider5)
        
paramsOne.combineLatest(paramsTwo)
    .debounce(for: 0.3, scheduler: DispatchQueue.main)
    .subscribe(subscriber)

请注意,我还必须将我的订阅者期望的输入从 (Double, Double, Double, Double, Double) 更改为 ((Double, Double, Double), (Double, Double)),并且编译器给了我一个误导和混淆的错误(关于调度程序的一些东西),直到我想通了发现输入类型错误。

扩展 Leonid 的回答:如果您需要对转换功能的支持,您需要这样的东西:

    public func combineLatest<P, Q, R, Y, T>(
            _ publisher1: P,
            _ publisher2: Q,
            _ publisher3: R,
            _ publisher4: Y,
            _ transform: @escaping (Self.Output, P.Output, Q.Output, R.Output, Y.Output) -> T) ->
            AnyPublisher<T, Self.Failure> where
    P: Publisher,
    Q: Publisher,
    R: Publisher,
    Y: Publisher,
    Self.Failure == P.Failure,
    P.Failure == Q.Failure,
    Q.Failure == R.Failure,
    R.Failure == Y.Failure {
        Publishers.CombineLatest(combineLatest(publisher1, publisher2, publisher3), publisher4)
                  .map { tuple, publisher4Value in
                      transform(tuple.0, tuple.1, tuple.2, tuple.3, publisher4Value)
                  }
                  .eraseToAnyPublisher()
    }