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]