arrays - Swift:改变结构中的数组

标签 arrays swift replace sub-array

我正在尝试在 Swift 中创建一个 Matrix 类,但在 self.data[row * columns..<(row + 1) * columns] = data 上收到错误我的线 setRow()功能。错误是“无法将类型“[Double]”的值分配给类型“ArraySlice””

struct Matrix: CustomStringConvertible {
    let rows:Int
    let columns:Int
    var data:[Double]

    // Description
    public var description: String {
        var description = ""
        for r in 0..<rows {
            description += data[r * columns..<(r + 1) * columns].description + "\n"
        }
        return description
    }

    // Initialisation
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        self.data = Array(repeating: 0.0, count: rows * columns)
    }

    init(rows: Int, columns: Int, data:[Double]) {
        assert(data.count == (rows * columns),"Number of elements must equal rows * columns")
        self.rows = rows
        self.columns = columns
        self.data = data
    }

    // Validity
    func validRow(row: Int) -> Bool {
        return row > 0 && row < rows
    }

    func validColumn(column: Int) -> Bool {
        return column > 0 && column < columns
    }

    func validIndex(row: Int, column: Int) -> Bool {
        return validRow(row: row) && validColumn(column: column)
    }

    // Setters and getters
    func get(row: Int, column: Int) -> Double {
        assert(validIndex(row: row,column: column), "Index out of range")
        return data[(row * columns) + column]
    }

    mutating func set(row: Int, column: Int, value: Double) {
        assert(validIndex(row: row,column: column), "Index out of range")
        data[(row * columns) + column] = value
    }

    func getRow(row: Int) -> [Double] {
        assert(validRow(row: row), "Index out of range")
        return Array(data[row * columns..<(row + 1) * columns])
    }

    mutating func setRow(row: Int, data:[Double]) {
        assert(validRow(row: row), "Index out of range")
        assert(data.count == columns, "Data must be same length ans the number of columns")
        self.data[row * columns..<(row + 1) * columns] = data
    }

    // Swapping
    mutating func swapRow(row1: Int, row2: Int) {
        assert(validRow(row: row1) && validRow(row: row2), "Index out of range")
        let holder = getRow(row: row2)
        setRow(row: row2, data: getRow(row: row1))
        setRow(row: row1, data: holder)
    }
}

最佳答案

正如错误所述,Array 的范围下标处理 ArraySlice ,而不是数组

一个解决方案,如 @vacawama says ,就是创建整个输入数组的一个切片。这可以通过使用数组的 indices 下标来完成:

mutating func setRow(row: Int, data newData: [Double]) {
    assert(validRow(row: row), "Index out of range")
    assert(data.count == columns, "Data must be same length ans the number of columns")
    data[row * columns ..< (row + 1) * columns] = newData[newData.indices]
}

或者在 Swift 4 中,您可以利用 the ... 'operator' ,它执行完全相同的操作:

data[row * columns ..< (row + 1) * columns] = newData[...]

但在我看来,一个更好的工具是 replaceSubrange(_:with:) :

mutating func replaceSubrange<C>(_ subrange: Range<Int>, with newElements: C) 
     where Element == C.Element, C : Collection

因为它允许您处理新元素的任意Collection,这意味着您还可以使setRow通用:

mutating func setRow<C : Collection>(row: Int, data newData: C)
    where C.Iterator.Element == Double { // <- in Swift 4, remove ".Iterator"

    assert(validRow(row: row), "Index out of range")
    assert(data.count == columns, "Data must be same length ans the number of columns")
    data.replaceSubrange(row * columns ..< (row + 1) * columns, with: newData)
}

关于arrays - Swift:改变结构中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45102527/

相关文章:

arrays - 运行多个异步任务并在所有任务完成后收到通知

swift - Xcode 12 Storyboard缩放窗口

swift - 替换 Storyboard 中的 ViewController,同时保留 Segues

javascript - 使用 jQuery 查找和替换 HTML 字符串

python替换数据框 Pandas 中所有列的多个值

c - 使用堆栈从数组中删除最后输入的偶数

c - 在 while 循环中将值存储在数组中

vba - 用 VBA 中的另一个单元格引用替换依赖项

javascript - Json 格式的对象到带有新键的简单数组

swift - 调用 Array.reduce(_ :_) from enumerated array