SwiftCombine:收集类似滑动窗口的功能

所以我有这个联合发布者说发出整数 - 1,2,3,4,5,6,7,8,9,10,11 ....

这些整数虽然并不总是存在。它们是即时生成并发送给发布者的。

我知道 collect 运算符,当它被称为 .collect(5) 时给我 - [1,2,3,4,5], [6,7,8,9,10], ...

我正在寻找的是有点像 buffer 和 collect 组合 - [1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7] ...

有没有办法在不编写自定义运算符的情况下做到这一点?如果自定义运算符是可行的方法,您能否提供一些指导,我之前没有编写自定义运算符。我希望从示例中可以清楚地了解我的要求。

谢谢

编辑

这有效,但我不确定这是否是最佳解决方案 -

publisher.zip(
    publisher.dropFirst(),
    publisher.dropFirst(2))

回答

您可以使用scan运算符来实现此效果。Scan使您能够累积一个值 - 在这种情况下是一个先前值的数组 - 然后发出它。您只需要删除最初的 N-1 个较小的数组。

sliding(window:)为方便起见,您可以创建自定义运算符:

extension Publisher {
    func sliding(window: Int) -> AnyPublisher<[Output], Failure> {
        if window < 1 { return Empty().eraseToAnyPublisher() }
        return self
           .scan([], { arr, value in
               if arr.count < window {
                   return arr + [value]
               } else {
                   return arr.dropFirst() + [value]
               }
           })
           .dropFirst(window - 1)
           .eraseToAnyPublisher()
   }
}

用法是:

[1,2,3,4,5,6,7,8,9,10].publisher
   .sliding(window: 5)
   .sink { print($0) }

输出将是:

[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
[6, 7, 8, 9, 10]


以上是SwiftCombine:收集类似滑动窗口的功能的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>