Access tuples by subscript

4.1k views Asked by At

Let's say I have this code:

let tuples = ("1", 2, "3", "4", "5", "6", "7", false)

func tableView(tableView:NSTableView, viewForTableColumn tableColumn:NSTableColumn?, row:Int) -> NSView?
{
    let valueForView = tuples[row]
}

Is there any way to access tuples by subscript?

4

There are 4 answers

4
Arbitur On BEST ANSWER

What you want is not possible with tuples and if you dont want to cast everything later-on your only option is struct or class. struct seems like a better choise :)

struct MyStruct {
    let opt1 = 0
    let opt2 = 0
    let opt3 = 0
    ...
    let boolThing = false
}
6
Ben-G On

No, you can only access tuple elements by directly specifying the index, e.g.

tuples.5

For your purpose you should simply use an array.

1
Mick MacCallum On

This actually is possible if you're willing to make a wrapper around your tuple. That being said, this is terrible, don't ever do this. The suggestions made in the other answers are practically a lot better, but for education purposes, here's my example.

struct TupleWrapper {
    let tuple: (String, Int, String, String, String, String, String, Bool)    
    let count: Int
    private let mirrors: [MirrorType]

    subscript (index: Int) -> Any {
        return mirrors[index].value
    }

    init(tuple: (String, Int, String, String, String, String, String, Bool)) {
        self.tuple = tuple

        var mirrors = [MirrorType]()
        let reflected = reflect(tuple)

        for i in 0..<reflected.count {
            mirrors.append(reflected[i].1)
        }

        self.mirrors = mirrors
        self.count = mirrors.count
    }
}

let wrapper = TupleWrapper(tuple: ("1", 2, "3", "4", "5", "6", "7", false))
wrapper[0] // "1"
wrapper[wrapper.count - 1] // false

The code above uses Swift's reflection APIs to get the logical children of your tuple object and add their mirrors to an array on which we can subscript for each mirror's value. This is fairly straight forward, but as you'd expect, since we're working with tuples here, this can't really be made dynamic in any way. The wrapper has to be made for a specific tuple type.

For some related reading, see NSHipster's recent MirrorType article.

1
Thanh Pham On

It is kind of possible using reflection:

Mirror(reflecting: tuples).children[AnyIndex(row)].value