【问题标题】:How to construct an n-dimensional array from data如何从数据构造一个 n 维数组
【发布时间】:2023-03-30 03:45:01
【问题描述】:

我想创建一个函数,它接收一个一维数字数组和一个形状,并返回一个数组,其中包含那些具有给定形状的数字。例如,如果我给它数组 [1, 2, 3, 4] 和形状 [2, 2],我希望它给我二维数组 [[1, 2], [3, 4]]。

我知道这很简单,但我的问题是指定返回类型。 我想避免只使用该函数的 [Any] 返回类型。就像给定的形状是二维的一样,返回类型应该是 [[Int]]、3 维 [[[Int]]] 等。我如何指定具有任意维数的整数数组作为返回类型?这甚至可能吗?

我对 swift 还很陌生,所以我还没有完全理解它的整个哲学。谢谢!

【问题讨论】:

    标签: arrays swift multidimensional-array


    【解决方案1】:

    您所描述的是一个矩阵。这与数组数组不同。比如下面是合法的[[Int]],却是非法的Matrix2:

    [[1, 2], [1]]
    

    Swift 没有内置的矩阵类型。你必须建立你自己的。有很多小项目可以寻找灵感。我不知道是否真的有足够的能力考虑完整的实现,但它们足以让你走上正确的轨道。他们通常希望包含 Accelerate,如果您不需要它,这会大大增加复杂性。

    任何 Matrix 类型的核心,如果你想构建自己的,是这样的:

    struct Matrix {
        private var storage: [Int]
        let rows: Int
        let columns: Int
    
        init(rows: Int, columns: Int) {
    
            precondition(rows > 0 && columns > 0)
    
            self.rows = rows
            self.columns = columns
            self.storage = Array(repeating: 0, count: rows * columns)
        }
    
        subscript(row: Int, column: Int) -> Int {
            get {
                return storage[row * columns + column]
            }
            set {
                storage[row * columns + column] = newValue
            }
        }
    }
    

    关键是存储只是一个扁平的元素数组,你可以按行和列下标。

    这个设计的一个好处是你的问题几乎是微不足道的,因为你的输入正是存储。

    extension Matrix {
        enum Error: Swift.Error {
            case invalidShape
        }
    
        init(rowMajorValues: [Int], rows: Int, columns: Int) throws {
            self.init(rows: rows, columns: columns)
            guard storage.count == rowMajorValues.count else {
                throw Error.invalidShape
            }
            storage = rowMajorValues
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-29
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      相关资源
      最近更新 更多