Swift: how to declare a 2d array (grid or matrix) in Swift to allow random insertion

I need to be able to store cell information in a 2d matrix or grid. The data is not contiguous, so I may need to store the data in 5.5 when there is no data in the lower rows and columns.

My first thought was an array of arrays with dynamic size. But Swift arrays have borders that don't grow automatically. If I try to put something in index 5, and it exceeds its current size, it crashes with an exception from outside.

Is there a collection class in Swift or Cocoa that supports random access to the grid. NSArray also does not support it.

Another thought was to store items in a dictionary and use a tuple of a row, column as a key. However, tuples are not hashed and cannot be used as a key for a dictionary.

My current approach is to initialize an array with a given size filled with zeros. Is there a better way?

+6
source share
1 answer

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 } } } 
+4
source

Source: https://habr.com/ru/post/977218/


All Articles