我需要能够在2d矩阵或网格中存储有关单元格的信息.数据不是连续的,因此当较低的行和列没有数据时,我可能需要将数据存储在5,5.
我的第一个想法是动态调整大小的数组.但Swift数组的边界不会自动增长.如果我尝试在索引5处放置一些超出其当前大小的内容,则会因超出范围异常而失败.
Swift或Cocoa中是否有一个支持随机访问网格的集合类. NSArray也不支持它.
另一个想法是将元素存储在字典中,并使用行,列的元组作为键.但是,元组不可清除,不能用作字典的键.
我目前的方法是使用填充空值的集合大小预初始化数组.
有没有更好的办法?
这是一个非常基本的实现,使用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"
as 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"]
数组后端版本
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
}
}
}