eharo2
eharo2

Reputation: 2642

Is there a better way to have a Swift array with names associated to index numbers?

In Swift, I want to have an array of items and then to be able to access those items by name or by index. The array is a fixed size array with 3 elements.

I have the following implementation using a struct

struct Boxes {
    var array: [Int]!
    var a: Int {
        get { return array[0] }
        set { array[0] = newValue }
    }
    var b: Int {
        get { return array[1] }
        set { array[1] = newValue }
    }
    var c: Int {
        get { return array[2] }
        set { array[2] = newValue }
    }
    init() {
        self.array = Array<Int>(repeating: 0, count: 3)
    }
}

And then, use it as follows:

var box = Boxes()
box.a = 1
box.b = box.array[0]
box.array[0] = 2
box.b = box.a

Is there a simpler, more elegant/concise form to do this?

Upvotes: 0

Views: 90

Answers (2)

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119828

struct Boxes {

    var array: [Int] {
        get { return [a, b, c] }
        set { (a, b, c) = (newValue[0], newValue[1], newValue[2]) }
    }

    var (a, b, c) = (0, 0 ,0)
}

Note that it is based on this sentence: fixed size array with 3 elements

Exact same usage:

var box = Boxes()
box.a = 1
box.b = box.array[0]
box.array[0] = 2
box.b = box.a

Extra: You can add custom initializer if you want to init with an array:

init(array: [Int] = [0, 0, 0]) {
    self.array = array
}

Upvotes: 2

Sweeper
Sweeper

Reputation: 273213

How about using an enum to store name-to-index associations, and add a subscript to Boxes to access the array:

enum BoxName : Int {
    case a, b, c
}

struct Boxes {
    var array: [Int]!

    subscript(_ name: BoxName) -> Int {
        get { return array[name.rawValue] }
        set { array[name.rawValue] = newValue }
    }

    init() {
        self.array = Array<Int>(repeating: 0, count: 3)
    }
}

// usage:

var box = Boxes()
box[.a] = 1
box[.b] = box.array[0]
box.array[0] = 2
box[.b] = box[.a]

Now when you want to add a new element and a new name in the array, you just need to add a new enum case.

Upvotes: 1

Related Questions