Reputation: 156
I have this loop, decrementing an integer by division, in Swift 2.
for var i = 128; i >= 1 ; i = i/2 {
//do some thing
}
The C-style for loop is deprecated, so how can I convert this to Swift 3.0?
Upvotes: 3
Views: 414
Reputation: 539975
Quite general loops with a non-constant stride can be realized
with sequence
:
for i in sequence(first: 128, next: { $0 >= 2 ? $0/2 : nil }) {
print(i)
}
i
is a constant and its scope is
restricted to the loop body.$0 >= 2
instead of i >= 1
), and the loop is always executed
at least once, for the first value.One could also write a wrapper which resembles the C-style for loop more closely and does not have the listed disadvantages (inspired by Erica Sadun: Stateful loops and sequences):
public func sequence<T>(first: T, while condition: @escaping (T)-> Bool, next: @escaping (T) -> T) -> UnfoldSequence<T, T> {
let nextState = { (state: inout T) -> T? in
guard condition(state) else { return nil }
defer { state = next(state) }
return state
}
return sequence(state: first, next: nextState)
}
and then use it as
for i in sequence(first: 128, while: { $0 >= 1 }, next: { $0 / 2 }) {
print(i)
}
Upvotes: 6
Reputation: 299545
MartinR's solution is very generic and useful and should be part of your toolbox.
Another approach is to rephrase what you want: the powers of two from 7 down to 0.
for i in (0...7).reversed().map({ 1 << $0 }) {
print(i)
}
Upvotes: 3
Reputation: 107221
I'll suggest that you should use a while
loop to handle this scenario:
var i = 128
while i >= 1
{
// Do your stuff
i = i / 2
}
Upvotes: 3