Swift:如何在Swift中声明一个二维数组(网格或矩阵)以允许随机插入

Dav*_*vid 6 collections grid matrix swift

我需要能够在2d矩阵或网格中存储有关单元格的信息.数据不是连续的,因此当较低的行和列没有数据时,我可能需要将数据存储在5,5.

我的第一个想法是动态调整大小的数组.但是Swift数组的边界不会自动增长.如果我尝试在索引5处放置一些超出其当前大小的内容,则它会因超出范围异常而失败.

Swift或Cocoa中是否有一个支持随机访问网格的集合类.NSArray也不支持它.

另一个想法是将元素存储在字典中,并使用行,列的元组作为键.但是,元组不可清除,不能用作字典的键.

我目前的方法是使用填充空值的集合大小预初始化数组.有没有更好的办法?

rin*_*aro 4

这是一个非常基本的实现,用作Dictionary后端存储:

struct Matrix2D<KeyElem:Hashable, Value> {

    var _storage:[KeyElem:[KeyElem:Value]] = [:]

    subscript(x:KeyElem, y:KeyElem) -> Value? {
        get {
            return _storage[x]?[y]
        }
        set(val) {
            if _storage[x] == nil {
                _storage[x] = [:]
            }
            _storage[x]![y] = val
        }
    }
}

var matrix = Matrix2D<Int, String>()

matrix[1,2] = "foo"
Run Code Online (Sandbox Code Playgroud)

作为DictionaryLiteralConvertible

extension Matrix2D:DictionaryLiteralConvertible {

    typealias Key = (x:KeyElem, y:KeyElem)

    init(dictionaryLiteral elements: (Key, Value)...) {
        for (key, val) in elements {
            self[key.x, key.y] = val
        }
    }
}

var matrix:Matrix2D = [(1,2):"foo", (2,3):"bar"]
Run Code Online (Sandbox Code Playgroud)

Array后端版本

struct Matrix2D<T> {

    var _storage:[[T?]] = []

    subscript(x:Int, y:Int) -> T? {
       get {
            if _storage.count <= x {
                return nil
            }
            if _storage[x].count <= y {
                return nil
            }
            return _storage[x][y]
        }
        set(val) {
            if _storage.count <= x {
                let cols = [[T?]](count: x - _storage.count + 1, repeatedValue: [])
                _storage.extend(cols)
            }
            if _storage[x].count <= y {
                let rows = [T?](count: y - _storage[x].count + 1, repeatedValue: nil)
                _storage[x].extend(rows)
            }
            _storage[x][y] = val
        }
    }
}
Run Code Online (Sandbox Code Playgroud)