swift - Swift Combine:使用类似滑动窗口的功能进行收集
问题描述
所以我有这个联合发布者说发出整数 - 1,2,3,4,5,6,7,8,9,10,11 ....
这些整数虽然并不总是存在。它们是即时生成的并发送给发布者。
我知道收集运算符,当说它被称为 .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]
推荐阅读
- node.js - Is possible node.js interaction with JMS queue?
- c# - 登录 Blazor 应用程序时重定向错误
- javascript - 表单仅在 safari 上不使用 javascript 提交
- c# - 从数组中创建所有变体而不重复 [C#]
- java - 由于某种原因在 Vaadin 7 中未创建 Servlet
- java - Spring 如何“神奇地”知道要使用哪种 Bean 类型?
- c - 在 Ada 中访问 C 字符串时出现分段错误
- reactjs - MainApplication.java 上的 React-Native-Reanimated 错误
- java - 降序排序
- java - 如何模拟特定的阅读文件?