我正在试图弄清楚如何将数组拆分成重叠的块.

例如,以下是输入:

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

这是预期的输出(块大小为3):

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

我开始使用STRIDE(通过与Swift的黑客攻击):

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}

这当然会给出不正确的输出:

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

我找不到stride的任何变体来获得预期结果,所以就这样做了,使用了两个嵌套的for-loops:

extension Array {
    func chunked2(into size: Int) -> [[Element]] {
        var result: [[Element]] = []
        
        for i in 0...self.count {
            var chunk: [Element] = []
           
            for j in i..<i+size {
                if j < self.count {
                    chunk.append(self[j])
                }
            }
        
            if chunk.count == size {
                result.append(chunk)
            }
        }
        
        return result
    }
}

这是可行的,并给出了预期的结果.

问:我想知道我是否可以用一种更"快速"的方式重写它,使用像stridemap、也许reduce这样的函数或其他我遗漏的函数?

推荐答案

你所描述的叫做"窗口化".它在数字信号处理中非常常见,开箱即用.有关SWIFT算法包及其在SWIFT生态系统中的作用的更多信息,请参见Announcing Swift 算法rithms.

如果你想看看算法如何工作的例子,请查看the source.它们使用数据 struct WindowsOfCountCollection来实现它,而不是创建一堆ZIP等等.这通常更高效,因为窗口是按需生成的,并且不必预先分配一堆内存.

Swift相关问答推荐

通过withstickedContinuation传递通用类型T

如何把多个可观测性变成一个完备性?

修改数组中每个类实例的属性

与视图交互使工具栏&;标题消失

关闭 SwiftUI TabView 中的子视图

循环字典中的数组

SwiftUI如何能够在Text中使用字符串字面量来创建LocalizedStringKey?

为什么无法在 Swift 中使用AVFoundation扫描 QRCode

使用异步收集发布者值

从一个范围减go 多个范围

@Binding 在@StateObject 和 View 上被发布了两次?

如何在 Swift 中使用子定义覆盖父类扩展

如何删除桥头而不出错?

否定 #available 语句

Swiftwhere数组扩展

Swift 自定义字体 Xcode

try 在解除分配时加载视图控制器的视图... UIAlertController

Alamofire:如何全局处理错误

如何在 SwiftUI 中创建带有图像的按钮?

如何快速显示数组的所有元素?