【譯】Swift演算法俱樂部-二維陣列
本文是對 ofollow,noindex">Swift Algorithm Club 翻譯的一篇文章。
Swift Algorithm Club 是 raywenderlich.com 網站出品的用Swift實現演算法和資料結構的開源專案,目前在GitHub上有18000+:star:️,我初略統計了一下,大概有一百左右個的演算法和資料結構,基本上常見的都包含了,是iOSer學習演算法和資料結構不錯的資源。
:octopus: andyRon/swift-algorithm-club-cn 是我對Swift Algorithm Club,邊學習邊翻譯的專案。歡迎有興趣學習演算法和資料結構,有時間的小夥伴一起參與翻譯,歡迎issue,或者直接提交pull request。
本文的翻譯原文和程式碼可以檢視:octopus: swift-algorithm-club-cn/Array2D
在C和Objective-C中,您可以編寫下面程式碼,
int cookies[9][7];
製作9x7網格的cookies。 這將建立一個包含63個元素的二維陣列。 要在第3列和第6行找到cookie,您可以寫:
myCookie = cookies[3][6];
這段程式碼在Swift中不能成立的。 要在Swift中建立一個多維陣列,您可以編寫:
var cookies = [[Int]]() for _ in 1...9 { var row = [Int]() for _ in 1...7 { row.append(0) } cookies.append(row) }
然後,要查詢cookie,您可以寫:
let myCookie = cookies[3][6]
您還可以使用一行程式碼中建立上面的陣列:
var cookies = [[Int]](repeating: [Int](repeating: 0, count: 7), count: 9)
這看起來很複雜,但您可以使用輔助函式簡化它:
func dim<T>(_count: Int,_value: T) -> [T] { return [T](repeating: value, count: count) }
譯註:這邊的 dim
,應該是 dimension
(維度)的縮寫。
然後,你可以這樣建立陣列:
var cookies = dim(9, dim(7, 0))
Swift推斷陣列的資料型別必須是 Int
,因為您指定了 0
作為陣列元素的預設值。 要使用字串陣列,您可以編寫:
var cookies = dim(9, dim(7, "yum"))
dim()
函式可以更容易地建立更多維度的陣列:
var threeDimensions = dim(2, dim(3, dim(4, 0)))
以這種方式使用多維陣列或多個巢狀陣列的缺點是無法跟蹤什麼維度代表什麼。
然而,您可以建立自己的型別,其作用類似於二維陣列,使用起來更方便:
public struct Array2D<T>{ public let columns: Int public let rows: Int fileprivate var array: [T] public init(columns: Int, rows: Int, initialValue: T) { self.columns = columns self.rows = rows array = .init(repeating: initialValue, count: rows*columns) } public subscript(column: Int, row: Int) -> T { get { precondition(column < columns, "Column\(column)Index is out of range. Array<T>(columns:\(columns), rows:\(rows))") precondition(row < rows, "Row\(row)Index is out of range. Array<T>(columns:\(columns), rows:\(rows))") return array[row*columns + column] } set { precondition(column < columns, "Column\(column)Index is out of range. Array<T>(columns:\(columns), rows:\(rows))") precondition(row < rows, "Row\(row)Index is out of range. Array<T>(columns:\(columns), rows:\(rows))") array[row*columns + column] = newValue } } }
譯註: precondition(_:_:file:line:)
函式類似 assert
,滿足條件會造成程式的提前終止並丟擲錯誤資訊,詳細檢視 官方文件 。此處有來表示當下標超過範圍的提示,效果如下:

Array2D
是一個泛型,因此能夠支援所有型別物件,而不是隻能是數字
建立 Array2D
示例程式碼:
var cookies = Array2D(columns: 9, rows: 7, initialValue: 0)
通過使用下標函式,您可以從陣列中檢索一個物件:
let myCookie = cookies[column, row]
或者設定物件:
cookies[column, row] = newCookie
在內部, Array2D
使用單個一維陣列來儲存資料。 該陣列中物件的索引由 (row x numberOfColumns) + column
給出,但作為 Array2D
的使用者,您只需要考慮 column
和 row
,具體事件將 由 Array2D
完成。 這是將基本型別包裝成包裝類或結構中的優點。
作者: Matthijs Hollemans
翻譯: Andy Ron
校對: Andy Ron