Reputation: 180
With Swift 2.2 deprecating C-style loops, I now need to find an alternative for a for-loop where the iterator was changed within the loop conditionally. What is now the Swifty way for doing:
for var i = 1; i <= 10; i++ {
//do stuff
if checkCondition() {
i--
}
}
Upvotes: 0
Views: 214
Reputation: 44
C's For
loop will simply be replaced with Swift's For-In
Loops. That means that this:
for var i = 1; i <= 10; i++ {
//do stuff
if checkCondition() {
i--
}
}
Becomes This:
for i in 1...10 {
//do stuff
if checkCondition() {
i-=i
}
}
The 1...10
is the range over which we want to iterate: from 1
to 10
.
Upvotes: -1
Reputation: 126157
The iterator variable declared in a for
loop is scoped to a single pass through that loop, so if you want to change it across multiple passes through the loop you'll need to use a while
loop instead.
Also, since your intention seems to be "increment the loop counter only if checkCondition()
is false" you can do that more clearly with a single, conditional increment, instead of using a decrement to undo your increment. Here are a couple of examples of that:
var i = 1
while i <= 10 {
if !checkCondition() {
i += 1
}
}
var j = 1
while j <= 10 {
j = checkCondition() ? j : j + 1
}
And a one that's maybe a little silly, but might come in handy if you do this sort of thing a lot:
extension IntegerType {
mutating func incrementIf(@autoclosure condition: () -> Bool) {
if condition() {
self = self + 1
}
}
}
var k = 1
while k <= 10 {
k.incrementIf(!checkCondition())
}
Of course, there's the further question of whether you want to be following this counter-based pattern at all (as @Sulthan notes in comments). Part of why Swift is doing away with the C-style for loop is that many loops with a counter are actually using that counter to index a collection, which is a pattern better served by collection iteration. So you might instead do something like:
for item in collection {
process(item)
if item.needsMoreProcessing {
process(item) // some more
}
}
for item in collection {
while item.needsProcessing {
process(item)
}
}
If something like this is what your loop is actually doing, writing it this way makes your purpose much more clear to other readers of your code (including your future self).
Upvotes: 3
Reputation: 73196
With dynamic update of the iterate within the loop block, you're probably best off to use a similar while
loop
var i = 1
while(i <= 10) {
if checkCondition() {
i -= 1
}
print(i)
i += 1
}
Upvotes: 3