In Swift, the c-style for-loop is deprecated, so I am switching to the stride function.
In the first function, I use a c-style for-loop. In the second function, I used the stride function. createNumbers output is [8, 7, 6, 5, 4, 3, 2] createNumbers2 output is [8, 7, 6, 5, 4] I am trying to get the first output.
That means the stride function will ignore if I change the endIdx value. Is there a way to work around this, using stride, such that createNumbers2 also prints 3 and 2?
func createNumbers(lastNum: Int) -> [Int] {
var endIdx = lastNum
var answer : [Int] = []
for var i = 8; i >= endIdx; i -= 1 {
answer.append(i)
if i == 6 {
endIdx /= 2
}
}
return answer
}
func createNumbers2(lastNum: Int) -> [Int] {
var endIdx = lastNum
var answer : [Int] = []
for i in 8.stride(through: endIdx, by: -1) {
answer.append(i)
if i == 6 {
endIdx /= 2
}
}
return answer
}
print(createNumbers(4)) // [8, 7, 6, 5, 4, 3, 2]
print(createNumbers2(4)) // [8, 7, 6, 5, 4]
The stride
method...
Returns the sequence of values (self, self + stride, self + stride + stride, ... last) where last is the last value in the progression less than or equal to end.
So, as you noted, when you invoke the stride
here
for i in 8.stride(through: endIdx, by: -1) {
the sequence is generated. Changing endIdx
after this line will NOT change the sequence the for in
will use.
Let's look at the logic you want to execute. Maybe we can find a better implementation.
Please correct if I am wrong.
You want to input an integer
lastNum
IF lastNum > 6 THEN OUTPUT 8,7
ELSE OUTPUT 8,7,... [lastNum/2]
Right?
Then you can write it this way
func numbers(lastNum: Int) -> [Int] {
let biggest = 8
guard lastNum <= biggest else { return [] }
let smallest = lastNum > 6 ? lastNum : lastNum / 2
return [Int](smallest...biggest).reverse()
}
numbers(4) // [8, 7, 6, 5, 4, 3, 2]
createNumbers(-1) == numbers(-1) // true
createNumbers(0) == numbers(0) // true
createNumbers(1) == numbers(1) // true
createNumbers(2) == numbers(2) // true
createNumbers(3) == numbers(3) // true
createNumbers(4) == numbers(4) // true
createNumbers(5) == numbers(5) // true
createNumbers(6) == numbers(6) // true
createNumbers(7) == numbers(7) // true
createNumbers(8) == numbers(8) // true
createNumbers(9) == numbers(9) // true
This is just my point of view. I know the for in
construct is still perfectly available in Swift. However building a value (an array in this case) using a for in
does force us to use mutable values and imperative code. We should avoid both as much as possible because immutable values are safer and declarative code is more clear and potentially faster.