简体   繁体   中英

Swift 3 - How do you initialise a multi-dimensional string array?

If I want to create a four dimensional string array I can type:

var array4 = [[[[String]]]]() 

If I want to initialise a single dimensional array I can use:

var array1 = [String](repeating: nil, count 10)

So how do I initialise a four dimensional string array?

var array4 = [[[[String]]]](repeating: nil, count: 10)

Doesn't work and gives an "Expression type is ambiguous" error.

You are wrong your declaration of array1 will also give you error.

var array1 = [String](repeating: nil, count: 10) //This will not compile

Will also give you error

Expression type '[String]' is ambiguous without more context"

Because you cannot set nil value to String you can set it String? , So you need to declare array with type [String?] .

var array1 = [String?](repeating: nil, count: 10) //This will compile

Same goes for array4 . You can declare array4 like this way

var array4 = [[[[String]]]?](repeating: nil, count: 10) //With nil objects

Or

var array4 = [[[[String]]]](repeating: [], count: 10) //With empty array objects

I expect that you want to actually do is declare a 4D array of a specified size, and then fill it by referring to the indices a[0][1][0][1] = "something" .

Let's suppose for the sake of example that you want a string at each corner of a hypercube (the only "concrete" example I can think of off the top of my head for a 4D array is 4D geometry). Then the vertex indices are going to be [0,0,0,0] [0,0,0,1] ... [1,1,1,0] [1,1,1,1] - 16 in total. Long-hand (possible for length = 2) we have:

var a: [[[[String]]]]
a = [
        [
            [
                ["?", "?"], ["?", "?"]
            ],
            [
                ["?", "?"], ["?", "?"]
            ],
        ],
        [
            [
                ["?", "?"], ["?", "?"]
            ],
            [
                ["?", "?"], ["?", "?"]
            ],
        ]
    ]

Now, we notice that each dimension is just a copy of the previous dimension n times (2 in this case), so to do it generically let's define:

func arrayOf<T>(el: T, count: Int) -> [T] {
    return [T](repeatElement(el, count: count))
}

It would be lovely to use recursion with a function like:

// func arrayOfArrays<T>(el: T, count: Int, depth: Int) -> ??? {
//     if depth == 1 { return arrayOf(el: el, count: count) }
//     return arrayOf(el: arrayOfArrays(el: el, count: count, depth: depth - 1), count: count)
// }
// a1:[[[[String]]]] = arrayOfArrays(el:"?", count: 2, depth: 4)

but what does it return? Generics can't cope with this, so we have to do it longhand:

var a1: [[[[String]]]]

a1 = arrayOf(el: arrayOf(el: arrayOf(el: arrayOf(el: "?", count: 2), count: 2), count: 2), count: 2)

a1[0][0][0][0] // "?" as expected
a1[1][1][1][1] = "!?"
a1[1][1][1][1] // "!?" as required
typealias TwoDimensionArray<T> = [Array<T>]
typealias ThreeDimensionArray<T> = [TwoDimensionArray<T>]
typealias FourDimensionArray<T> = [ThreeDimensionArray<T>]

var array4 = FourDimensionArray<String>.init(repeating: [], count: 10)

print(array4) // [[], [], [], [], [], [], [], [], [], []]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM