Swift中多维数组的语法是什么?

时间:2015-03-09 07:14:55

标签: arrays swift multidimensional-array

CO粉丝:在你得出结论之前它是重复的,有2种不同的数组,我觉得不太受欢迎。

到目前为止,我只看到像[[Int]]这样的锯齿状数组的语法,但我找不到有关平面多维数组的任何信息。那么type的语法是什么(比如Ints的2d数组)以及用数据初始化这样的数组的语法是什么?有没有[2, 3 ;; -1, 0]

2 个答案:

答案 0 :(得分:4)

是的,内置任何东西(据我所知)。您可以定义自定义类/结构(如Most efficient way to access multi-dimensional arrays in Swift?中所示 或How to Declare a Multidimensional Boolean array in Swift?)带有下标运算符,以便a[0,0] = 1有效。

这是这些解决方案的混合物,但作为一个 通用struct而不是class。我也改变了顺序 行和列参数因为我发现更自然:

struct Array2D<T : IntegerLiteralConvertible > {
    let rows : Int
    let cols : Int
    var matrix: [T]

    init(rows : Int, cols : Int) {
        self.rows = rows
        self.cols = cols
        matrix = Array(count : rows * cols, repeatedValue : 0)
    }

    subscript(row : Int, col : Int) -> T {
        get { return matrix[cols * row + col] }
        set { matrix[cols*row+col] = newValue }
    }
}

我不知道如何从字面上创建这样的东西 [2, 3 ;; -1, 0]。但您可以从嵌套数组中初始化它:

extension Array2D {

    init(_ elements: [[T]]) {
        let rows = elements.count
        let cols = elements[0].count
        self.init(rows: rows, cols: cols)
        for i in 0 ..< rows {
            assert(elements[i].count == cols, "Array must have same number of elements for each row")
            self.matrix.replaceRange(cols * i ..< cols * (i+1), with: elements[i])
        }
    }
}

示例:

let array = Array2D([[1, 2, 3], [4, 5, 6]])
println(array.rows)  // 2
println(array.cols)  // 3
println(array[1, 2]) // 6
println(array[1, 0]) // 4

您还可以实现ArrayLiteralConvertible协议从嵌套数组文字初始化2d数组:

extension Array2D : ArrayLiteralConvertible {

    init(arrayLiteral elements: [T]...) {
        self.init(elements)
    }
}

示例:

let array : Array2D = [[1, 2, 3], [4, 5, 6]]

对于方阵(rows == columns),您也可以从普通数组中初始化它:

extension Array2D {

    init(_ elements: [T]) {
        let rows = Int(sqrt(Double(elements.count)))
        assert(rows * rows == elements.count, "Number of array elements must be a square")
        self.init(rows: rows, cols: rows)
        self.matrix = elements
    }
}

示例:

let squareArray = Array2D([2, 3, -1, 0])
println(squareArray.rows)  // 2
println(squareArray.cols)  // 3
println(squareArray[1, 0]) // -1

答案 1 :(得分:0)

支持任意数量维度的示例实现:

struct ArrayMultiDimension<T> {
    private var _base:[T]
    let _dimensions: [Int]

    init(initialValue: T, dimensions:Int...) {
        _base = Array(count: reduce(dimensions, 1, *), repeatedValue: initialValue)
        _dimensions =  dimensions
    }
    private func _position2idx(position:[Int]) -> Int {
        assert(position.count == _dimensions.count)
        return reduce(Zip2(_dimensions, position), 0) {
            assert($1.0 > $1.1)
            return $0 * $1.0 + $1.1
        }
    }
    subscript(position:Int...) -> T {
        get { return _base[_position2idx(position)] }
        set { _base[_position2idx(position)] = newValue }
    }
}

// Usage:

var array3d = ArrayMultiDimension(initialValue: "", dimensions: 4,3,2)

for x in 0 ..< 4 {
    for y in 0 ..< 3 {
        for z in 0 ..< 2 {
            array3d[x,y,z] = "\(x)-\(y)-\(z)"
        }
    }
}

array3d[1,2,0] = "foo"

但是,这可能会很慢......