UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Does Swift have multiple dimension Arrays?

Forums > Swift

var a = [[1,2,3],[4,5,6]]

You can access a pseudo 2d element as

a[0][0]

But from my testing, it appears that Swift treats this as an array of arrays. There is no requirement that the two sub-arrays be the same length.

a[[1,2,3],[4,5]]

Is also valid.

FWIW,

a[[1,2],["one","two"]]

is also valid as Swift treats the outer array as an Array of Any.

So is there a way to create a true multi-dimensional array, where all the rows have to be the same length and the same type?

Mark

2      

You might be better off doing an array of structs (or classes if that's your thing) to ensure structure. For my money, that's how I'd do it rather than rely on the constant implied structure in a world of ambiguity. But as you noted, most of the declarations you defined can be gamed if you care to do so.

I'm all about structure, and housing a finite-structure struct in an array just feels right in this context. If swift had more complete coverage for typedefs, I'd say you could alias up something like:

typealias Thing = [Int, Int, Int] // <-- does this even work? I don't know. Probably not.

Then do:

var things = [Thing]()

Slightly less overhead than defining a struct, but again, I think that's just blue-sky wishing. It also doesn't really fix the problem since Swift doesn't support fixed-length arrays (as far as I know), so you're still looking at less rigidity than you want.

2      

Check out this example from the Swift docs on subscripts.

struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0.0, count: rows * columns)
    }
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}

Usage example:

var matrix = Matrix(rows: 2, columns: 2)
matrix[1, 1] = 17
matrix[0, 1] = 11
print(matrix[1, 0])  //0.0
print(matrix)  //Matrix(rows: 2, columns: 2, grid: [0.0, 11.0, 0.0, 17.0])

You can adjust this as needed for your specific use case.

It's not exactly a multidimensional array behind the scenes, but it acts like one for the user.

Oh, I forgot about this! While I haven't really used it, only watched the Developer video about it, there's Apple's new TabularData framework. I don't know if that would work for you, but it might be worth checking out.

2      

Does this work?

typealias Thing = [Int, Int, Int]

No. FWIW, I find Swift Playgrounds quite handy for evaluating and testing snippets of code.

Thanks for the code on subscripts. That will work as a matrix for many uses while maintaing Swift's type safety, which my proposed code doesn't as it uses UnsafePointers.

Thanks for the reference to TabularData. While it's not something I can use in this app (yet), I can see where it will be useful for other things I need to do. It looks like TabularData and Swift Playgrounds could be a useful tool for ad hoc data analysis.

Mark

2      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.