Simon
Simon

Reputation: 2469

Using array values to init new array elements

I've put together the following sample code:

let tings = [1, 2, 4, 5, 6, 8]

class Foo {
    var number: Int
    init(something: Int) {
        self.number = something
    }
}

var list: [Foo] = []
for num in tings {
    var temp = Foo(something: tings[num])         //excbadinstruction invop
    list.append(Foo(something: 3))                //no error
    list.append(Foo(something: Int(4)))           //no error
    list.append(Foo(something: tings[num]))       //excbadinstruction invop
    list.append(Foo(something: Int(tings[num])))  //excbadinstruction invop
}

I dont get what the problem is with the last two lines as in my opinion things[num] also is of type Int, and same of course with the last row.

If I specify the type of things to be [Int], nothing changes (which isnt strange to me) I also have to explicitly state 'something:' which I didn't expect because it was the first and only argument of the initializer.

I hope anyone can explain this to me and/or give the right way to do this.

Upvotes: 0

Views: 81

Answers (1)

nhgrif
nhgrif

Reputation: 62052

Swift Playground is fun and all, but it's pretty terrible when it comes to debugging.

If we duplicate this code in an actual compilable and build able application, we get no build time warnings or errors. However, as soon as we hit play and run the code, the problem is obvious. The console prints:

fatal error: Array index out of bounds

Here's the problem... our array has six elements. That means the maximum accessible index is 5.

Look at our loop:

for num in tings {
    // do stuff
}

If we change the loop to print num, like this:

for num in tings {
    println(num)
}

You'll see that it prints our tings array:

1
2
4
5
6
8

Now let's access the the element at each index:

for num in tings {
    println(tings[num])
}

What prints?

2
4
6
8
fatal error: Array index out of range

What happened?

We tried to access the 6th index, because the fifth iteration of the loop, the fifth element of the array, is the Int 6. We're trying to access the 6th element, which is out of bounds for our array.


If you're trying to iterate of the elements of tings and instantiate a Foo for each element, you simply need this:

for num in tings {
    list.append(Foo(something: num))
}

Or as Paul points out in a comment, if you need the index, you can iterate through the loop as such:

for (index, value) in enumerate(tings) {
    // do stuff
}

Upvotes: 2

Related Questions