如何创建3D NSMutableArray

时间:2016-07-19 17:56:49

标签: ios swift nsmutablearray

如何创建Int的3D可变数组?

我希望能够通过说gsub来插入元素,而不必事先确定数组的大小。

2 个答案:

答案 0 :(得分:1)

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游乐场中的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]]]

答案 1 :(得分:1)

讨论(见下文最终代码)

这是一种方法:首先,我们使用下标来扩展_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]

现在我们可以扩展三维数组,使其具有一个方便的下标,可以像这样自动扩展:

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]]]

不幸的是,Optional HasDefault nilNilLiteralConvertible}可能会扩展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]]]

我强烈推荐这种方法,因为pickle.dump() s的整个目的是没有价值。

TL; DR /最终代码

Sub GPWireDifference()

'Prevent screen updating during execution
Application.ScreenUpdating = False

'Establishes the Unmatched Great Plains Values list
    Set BWGPValues = New Dictionary


'Creates a variable to check if Keys already exist in list
    Dim lookup As String
    'Creates a variable to store the unmatched amount
    Dim amount As Currency
    'Sets a variable to count the amount of items in the checked list
    lastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row


'Format all columns in the Calculation sheet to fit their contents
    Cells.EntireColumn.AutoFit
    'Formatting the numbers to the common "currency" type
    Range("B:E").NumberFormat = "$#,##0.00"
    Range("D2").Activate

    'Place entire range in memory as array
    Dim A() As Variant: A = Range("B2:B" & lastRow).Value2
    'Create Dictionary to contain all unqiue values from list
    'The dictionary will store a collection of indexes for that unique value
    Dim Au As New Dictionary
    For i = 1 To UBound(A)
        If Not Au.Exists(A(i, 1)) Then
            Au.Add A(i, 1), New Collection
        End If
        Au(A(i, 1)).Add i
        A(i, 1) = ""
    Next

    'Repeat above steps for list B
    Dim B() As Variant: B = Range("C2:C" & lastRow).Value2
    Dim Bu As New Dictionary
    For i = 1 To UBound(B)
        If Not Bu.Exists(B(i, 1)) Then
            Bu.Add B(i, 1), New Collection
        End If
        Bu(B(i, 1)).Add i
        B(i, 1) = ""
    Next

    'Loop through unique values in A
    'If found in B's unique value list then populate B indexes with value
    For Each k In Au
        If Bu.Exists(k) Then
            For Each i In Bu(k)
                B(i, 1) = k
            Next
        End If
    Next

    'Loop through unique values in B
    'If found in A's unique value list then populate A indexes with value
    For Each k In Bu
        If Au.Exists(k) Then
            For Each i In Au(k)
                A(i, 1) = k
            Next
        End If
    Next

    'Assign Array back to Range
    Range("D2:D3000") = A
    Range("E2:E3000") = B

'Creates headers for the comparison rows
    Range("D1").Value = "GP to Wires:"
    Range("E1").Value = "Wires to GP:"


'Reformats the columns to fit all contents
    Cells.EntireColumn.AutoFit

End Sub