Senseful Senseful - 6 months ago 14
Swift Question

A concise way to not execute a loop now that C-Style for loops are going to be removed from Swift 3?

Imagine we have this code which works perfectly for

n >= 0
.

func fibonacci(n: Int) -> Int {
var memo = [0,1]
for var i = 2; i <= n; i++ {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}


If I remove the C-style for loop due to upcoming changes to Swift 3.0, I get something like this:

func fibonacci(n: Int) -> Int {
var memo = [0,1]
for i in 2...n {
memo.append(memo[i-1] + memo[i-2])
}
return memo[n]
}


While this works fine for
n >= 2
, it fails for the numbers
0
and
1
with this error message:


fatal error: Can't form Range with end < start


What's the most concise way to fix this code so it works properly for
0
and
1
?

(Note: It's okay, and even desirable, for negative numbers to crash the app.)




Note: I realize I could add a guard statement:

guard n >= 2 else { return memo[n] }


... but I'm hoping there is a better way to fix just the faulty part of the code (
2...n
).

For example, if there was a concise way to create a range that returns zero elements if
end < start
, that would be a more ideal solution.

Answer

To do this in a way that works for n < 2, you can use the stride method.

let startIndex = 2
let endIndex = n

for i in startIndex.stride(through: endIndex, by: 1) {
    memo.append(memo[i-1] + memo[i-2])
}