[英]How to create 3D NSMutableArray
如何創建Int的3D可變數組?
我希望能夠通過說arr[4][3][5] = 4
來插入元素,而不必事先確定數組的大小。
var z = [Int](count:10, repeatedValue: 0)
var y = [[Int]](count:10, repeatedValue: z)
var x = [[[Int]]](count:10, repeatedValue: y)
x[A][B][C] = 4
var val = x[2][1][1]
Xcode 8 Beta 2 Playground中的Swift 3
var z = [Int](repeatElement(0, count: 10))
var y = [[Int]](repeatElement(z, count: 10))
var x = [[[Int]]](repeatElement(y, count: 10))
可能的答案
var z = [0]
var y = [z]
var x = [y]
x[0][0].append(2)
x[0].append([1])
x.append([[3,5],[0]])
print(x)
x[0][0][0] = 2
print(x)
//Output
[[[0, 2], [1]], [[3, 5], [0]]]
[[[2, 2], [1]], [[3, 5], [0]]]
這是一種實現方法:首先,我們用下標擴展_ArrayType
,當訪問索引超出范圍時,該下標會自動擴展數組。 我們將使用給定的fallback
值數組:
extension _ArrayType {
subscript (extending pos: Int, fallback fallback: Generator.Element) -> Generator.Element {
mutating get {
while count <= pos { append(fallback) }
return self[pos]
}
mutating set {
while count <= pos { append(fallback) }
self[pos] = newValue
}
}
}
可以這樣使用:
var a : [Int] = []
a[extending: 3, fallback: 0] = 10
print(a) // [0, 0, 0, 10]
現在,我們可以擴展3維數組以具有方便的下標,該下標可以自動擴展:
extension _ArrayType where
Generator.Element : _ArrayType,
Generator.Element.Generator.Element : _ArrayType {
typealias T = Generator.Element.Generator.Element.Generator.Element
subscript (x: Int, y: Int, z: Int, `default`: T) -> T {
mutating get {
return self[extending: x, fallback: []][extending: y, fallback: []][extending: z, fallback: `default`]
}
mutating set {
self[extending: x, fallback: []][extending: y, fallback: []][extending: z, fallback: `default`] = newValue
}
}
}
用法:
var array : [[[Int?]]] = []
array[1, 1, 0, nil] = 10
array[2, 0, 1, nil] = 4
print(array) // [[], [[], [Optional(10)]], [[nil, Optional(4)]]]
現在,如果您希望通過事先告知特定類型的默認值應該更方便,可以創建一個HasDefault
協議:
protocol HasDefault {
static var `default` : Self { get }
}
並使用它擴展您的類型:
extension Int : HasDefault {
static var `default` = 0
}
extension Bool : HasDefault {
static var `default` = false
}
還要創建一個不帶最后一個參數的下標:
extension _ArrayType where
Generator.Element : _ArrayType,
Generator.Element.Generator.Element : _ArrayType,
Generator.Element.Generator.Element.Generator.Element : HasDefault {
typealias E = Generator.Element.Generator.Element.Generator.Element
subscript (x: Int, y: Int, z: Int) -> E {
mutating get {
return self[x, y, z, E.`default`]
}
mutating set {
self[x, y, z, E.`default`] = newValue
}
}
}
現在,可以按照您想要的方式使用它:
var array : [[[Int]]] = []
array[0, 1, 0] = 3
array[1, 2, 3] = 10
print(array[2, 0, 1]) // 0
print(array) // [[[], [3]], [[], [], [0, 0, 0, 10]], [[0, 0]]]
不幸的是,尚不能使用HasDefault
擴展Optional
(將為nil
),但是您可以為NilLiteralConvertible
s創建一個自定義下標, Optional
符合:
extension _ArrayType where
Generator.Element : _ArrayType,
Generator.Element.Generator.Element : _ArrayType,
Generator.Element.Generator.Element.Generator.Element : NilLiteralConvertible {
subscript (x: Int, y: Int, z: Int) -> Generator.Element.Generator.Element.Generator.Element {
mutating get {
return self[x, y, z, nil]
}
mutating set {
self[x, y, z, nil] = newValue
}
}
}
像這樣使用:
var array : [[[Int?]]] = []
array[0, 1, 0] = 3
array[1, 2, 3] = 10
print(array[2, 0, 1]) // nil
print(array) // [[[], [3]], [[], [], [nil, nil, nil, 10]], [[nil, nil]]]
我強烈推薦這種方法,因為Optional
的整個目的是不代表任何價值。
extension _ArrayType {
subscript (extending pos: Int, fallback fallback: Generator.Element) -> Generator.Element {
mutating get {
while count <= pos { append(fallback) }
return self[pos]
}
mutating set {
while count <= pos { append(fallback) }
self[pos] = newValue
}
}
}
extension _ArrayType where
Generator.Element : _ArrayType,
Generator.Element.Generator.Element : _ArrayType,
Generator.Element.Generator.Element.Generator.Element : NilLiteralConvertible {
subscript (x: Int, y: Int, z: Int) -> Generator.Element.Generator.Element.Generator.Element {
mutating get {
return self[extending: x, fallback: []][extending: y, fallback: []][extending: z, fallback: nil]
}
mutating set {
self[extending: x, fallback: []][extending: y, fallback: []][extending: z, fallback: nil] = newValue
}
}
}
var array : [[[Int?]]] = []
array[0, 1, 0] = 3
array[1, 2, 3] = 10
print(array[2, 0, 1]) // nil
print(array) // [[[], [3]], [[], [], [nil, nil, nil, 10]], [[nil, nil]]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.