lutrarutra
lutrarutra

Reputation: 474

Swift 3d Array creating

I want to create an array that is 3d. Array will be 5*5*infinite (the last or the innermost array will probably has like 3-5 object of type String).

I tried something like this:

var array3D = [[[String]]]()

and tried to add new string like this

array3D[ii][yy] += y.components(separatedBy: ";")

But had problems adding new arrays or strings to that. And got error of exc bad instruction

In school I have 5 lessons per day. So in week there is 25 lessons, and I want to make an iPhone app that represent my timetable.

Upvotes: 2

Views: 6060

Answers (2)

Luca Angeletti
Luca Angeletti

Reputation: 59516

I slightly modified the Matrix struct provided by The Swift Programming Language

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

Usage

Now you can write

var data = Matrix<String>(rows: 5, columns: 5)
data[0, 0] = ["Hello", "World"]
data[0, 0][0] // Hello

Upvotes: 3

rickster
rickster

Reputation: 126137

A multidimensional array is just an array of arrays. When you say

var array3D = [[[String]]]()

What you've created is one empty array, which expects the values you add to it to be of type [[String]]. But those inner arrays don't exist yet (much less the inner inner arrays inside them). You can't assign to array3D[ii] because ii is beyond the bounds of your empty array, you can't assign to array3D[ii][yy] because array3D[ii] doesn't exist, and you can't append to an array in array3D[ii][yy] because array3D[ii][yy] doesn't exist.

Because your outer and middle levels of array are fixed in size (5 by 5 by n), you could easily create them using Array.init(count:repeatedValue:):

let array3D = [[[String]]](count: 5, repeatedValue:
    [[String]](count: 5, repeatedValue: []))

(Here the innermost arrays are empty, since it appears you plan to always fill the by appending.)


However, it also looks like your use case expects a rather sparse data structure. Why create all those arrays if most of them will be empty? You might be better served by a data structure that lets you decouple the way you index elements from the way they're stored.

For example, you could use a Dictionary where each key is some value that expresses a (day, lesson, index) combination. That way the (day, lesson, index) combinations that don't have anything don't need to be accounted for. You can even wrap a nice abstraction around your encoding of combos into keys by defining your own type and giving it a subscript operator (as alluded to in appzYourLife's answer).

Upvotes: 3

Related Questions