Here is a very simple implementation using Dictionary as an internal repository:
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"]
Array backend version
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 } } }
source share