Reputation: 773
I'm currently in the process of updating some apps to the latest Swift 4 syntax and have run into a problem, and I'm sure I'm just missing something really obvious.
Initially my code was as follows:
let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
for(i = 0; i < newSequence.count; i++)
{
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
Initially I had three error with the above code, namely:
Value of type '[Int]' has no member 'shuffle'
C-style for statement has been removed in Swift 3
Unary operator '++' cannot be applied to an operand of type '@lvalue Int'
To address these I changed the code so that it's now as follows:
let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
while i < newSequence.count {i += 1
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
After changing the code and running a Product > Clean within Xcode, I no longer have any errors. However, when I use the app in the iOS Simulator it hangs at a certain point and checking within Xcode gives me the Thread 1: Fatal error: Index out of range
error on the following line of code:
let index = newSequence[I]
I've read through other questions about the same error in Swift (see: 1, 2, 3 and 4) but these don't seem to apply in my scenario.
I know I'm missing something really obvious here, but at present it's just escaping me.
Any thoughts?
Upvotes: 1
Views: 109
Reputation: 285290
The Swift 3+ equivalent of the code is
let indices : [Int] = [0,1,2,3]
let newSequence = indices.shuffle() // this seems to be a custom function
for i in 0..<newSequence.count
{
let index = newSequence[i]
if index == 0 { // no parentheses in Swift
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
}
Upvotes: 2
Reputation: 79776
Change position of (incrementing value) i
as shown in below code. (Value of i
is increment before it is used in loop operations, hence during final/last iteration of loop, value of i
becomes larger than array indices)
let indices : [Int] = [0,1,2,3]
//let newSequence = shuffle(indices)
let newSequence = indices.shuffle()
var i : Int = 0
while i < newSequence.count {
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
i += 1 // Update (increment) value for i at last
}
(As suggested by MartinR) This would be better than you did:
let indices : [Int] = [0,1,2,3]
let newSequence = indices.shuffle()
for (i, newSeqIndex) in newSequence.enumerated() {
if (newSeqIndex == 0) {
currentCorrectAnswerIndex = i
}
}
Upvotes: 2
Reputation: 6993
The reason for crash is that you increment i
, perform some operations with it, and only then check if it is not out of range. To get rid of this error just move i += 1
to the end of your closure.
But why not use fast enumeration? You're still trying to do a loop the old way, but with new syntax. Instead of doing it C way
var i : Int = 0
while i < newSequence.count {
let index = newSequence[i]
if(index == 0)
{
// we need to store the correct answer index
currentCorrectAnswerIndex = i
}
i += 1
}
do it the correct Swift way
for (index, value) in newSequence.enumerated() {
if value == 0 {
currentCorrectAnswerIndex = index
}
}
Upvotes: 2