How do a i+=2 for-loop in Swift? [duplicate] - swift

This question already has answers here:
Swift 3 for loop with increment
(5 answers)
Closed 5 years ago.
for example, a Java for-loop:
for(int i=0; i<5; i+=1){
//
}
convert to Swift
for index in 0..<5 {
}
but what if i+=2?
I'm new to Swift.. Maybe it's a stupid question, but will be appreciate if you answer it, thx! :-)

Check this
for index in stride(from: 0, to: 5, by: 2){
print(index)
}

You can use this way as well.
var first = 0
var last = 10
var add = 2
for i in sequence(first: first, next: { $0 + add })
.prefix(while: { $0 <= last }) {
print(i)
}
Output will be: 0,2,4,6,8,10

In case if your for loop was doing something more complex than adding constant value to index each iteration you may use something like that:
Assuming you have this for loop:
for(index = initial; condition(index); mutation(index)){
//
}
Where
initial — initial value constant of type T
condition — function (T) -> Bool, that checks if loop should end
mutation — function (T) -> T, that changes index value each iteration
Then it will be:
for index in sequence(first: initial, next: { current in
let next = mutation(current)
return condition(next) ? next : nil
}) {
//
}

Related

Swift for loop with stride that references itself [duplicate]

...or how can I use the index inside the for loop condition
Hey people
Since we're left with no c style for loops in swift 3 I can't seem to find a way to express a bit more complex for loops so maybe you can help me out.
If I were to write this
for(int i=5; num/i > 0; i*=5)
in swift 3 how would I do that?
The closes I came by was:
for i in stride(from: 5, through: num, by: 5) where num/i > 0
but this will of course iterate 5 chunks at a time instead if i being: 5, 25, 125 etc.
Any ideas?
Thanks
Using a helper function (originally defined at Converting a C-style for loop that uses division for the step to Swift 3)
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
// Return `nil` if condition is no longer satisfied:
guard condition(state) else { return nil }
// Update current value _after_ returning from this call:
defer { state = next(state) }
// Return current value:
return state
}
return sequence(state: first, next: nextState)
}
you can write the loop as
let num = 1000
for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) {
print(i)
}
A simpler solution would be a while-loop:
var i = 5
while num/i > 0 {
print(i)
i *= 5
}
but the advantage of the first solution is that the scope of the loop variable is limited to the loop body, and that the loop variable is a constant.
Swift 3.1 will provide a prefix(while:) method for sequences,
and then the helper function is no longer necessary:
let num = 1000
for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) {
print(i)
}
All of above solutions are "equivalent" to the given C loop.
However, they all can crash if num is close to Int.max
and $0 * 5 overflows. If that is an issue then you have to check
if $0 * 5 fits in the integer range before doing the multiplication.
Actually that makes the loop simpler – at least if we assume that
num >= 5 so that the loop is executed at least once:
for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) {
print(i)
}
For completeness: an alternative to the while loop approach is using an AnyIterator:
let num = 1000
var i = 5
for i in AnyIterator<Int>({
return i <= num ? { defer { i *= 5 }; return i }() : nil
}) {
// note that we choose to shadow the external i variable name,
// such that any access to i within this loop will only refer
// to the loop local immutable variable i.
print(i)
// e.g. i += 1 not legal, i refers to a constant here!
} /* 5
25
125
625 */
This method suffers from the same drawback as the while loop in that the loop "external" i variable persists outside and after the scope of the loop block. This external i variable is not, however, the i variable that is accessible within the loop body, as we let the loop body variable i shadow the external one, limiting access to i within the body to the immutable, temporary (loop scope local) one.

'+=' produces '()'. How can i return an incremented value from a closure [duplicate]

This question already has answers here:
How replace position++ code to make it Swift 3 compatible?
(2 answers)
Closed 6 years ago.
i'm using Swift3. This syntax gives me an error:
func countingClosure() -> (() -> Int) {
var counter = 0
let incrementCounter: () -> Int = {
return counter+=1;
}
return incrementCounter
}
I cant increment using counter++, since its deprecated.
Is there a alegant way to deal with this, so the first value i return will be 0 ?
I "hacky" way will be to initiate counter = -1. And increment it a line before.
counter+=1;
return counter;
Thanks.
Edit:
I've tried to search StackOverflow for this error, and didn't find an answer. This question was marked as duplicate, but there was no way i could find the relevant/original question.
Just another way, use defer to increment counter after return
func countingClosure() -> (() -> Int) {
var counter = 0
let incrementCounter: () -> Int = {
defer {
counter += 1
}
return counter
}
return incrementCounter
}

Express for loops in swift with dynamic range

...or how can I use the index inside the for loop condition
Hey people
Since we're left with no c style for loops in swift 3 I can't seem to find a way to express a bit more complex for loops so maybe you can help me out.
If I were to write this
for(int i=5; num/i > 0; i*=5)
in swift 3 how would I do that?
The closes I came by was:
for i in stride(from: 5, through: num, by: 5) where num/i > 0
but this will of course iterate 5 chunks at a time instead if i being: 5, 25, 125 etc.
Any ideas?
Thanks
Using a helper function (originally defined at Converting a C-style for loop that uses division for the step to Swift 3)
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
// Return `nil` if condition is no longer satisfied:
guard condition(state) else { return nil }
// Update current value _after_ returning from this call:
defer { state = next(state) }
// Return current value:
return state
}
return sequence(state: first, next: nextState)
}
you can write the loop as
let num = 1000
for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) {
print(i)
}
A simpler solution would be a while-loop:
var i = 5
while num/i > 0 {
print(i)
i *= 5
}
but the advantage of the first solution is that the scope of the loop variable is limited to the loop body, and that the loop variable is a constant.
Swift 3.1 will provide a prefix(while:) method for sequences,
and then the helper function is no longer necessary:
let num = 1000
for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) {
print(i)
}
All of above solutions are "equivalent" to the given C loop.
However, they all can crash if num is close to Int.max
and $0 * 5 overflows. If that is an issue then you have to check
if $0 * 5 fits in the integer range before doing the multiplication.
Actually that makes the loop simpler – at least if we assume that
num >= 5 so that the loop is executed at least once:
for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) {
print(i)
}
For completeness: an alternative to the while loop approach is using an AnyIterator:
let num = 1000
var i = 5
for i in AnyIterator<Int>({
return i <= num ? { defer { i *= 5 }; return i }() : nil
}) {
// note that we choose to shadow the external i variable name,
// such that any access to i within this loop will only refer
// to the loop local immutable variable i.
print(i)
// e.g. i += 1 not legal, i refers to a constant here!
} /* 5
25
125
625 */
This method suffers from the same drawback as the while loop in that the loop "external" i variable persists outside and after the scope of the loop block. This external i variable is not, however, the i variable that is accessible within the loop body, as we let the loop body variable i shadow the external one, limiting access to i within the body to the immutable, temporary (loop scope local) one.

For loop based on exponential increases [duplicate]

...or how can I use the index inside the for loop condition
Hey people
Since we're left with no c style for loops in swift 3 I can't seem to find a way to express a bit more complex for loops so maybe you can help me out.
If I were to write this
for(int i=5; num/i > 0; i*=5)
in swift 3 how would I do that?
The closes I came by was:
for i in stride(from: 5, through: num, by: 5) where num/i > 0
but this will of course iterate 5 chunks at a time instead if i being: 5, 25, 125 etc.
Any ideas?
Thanks
Using a helper function (originally defined at Converting a C-style for loop that uses division for the step to Swift 3)
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
// Return `nil` if condition is no longer satisfied:
guard condition(state) else { return nil }
// Update current value _after_ returning from this call:
defer { state = next(state) }
// Return current value:
return state
}
return sequence(state: first, next: nextState)
}
you can write the loop as
let num = 1000
for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) {
print(i)
}
A simpler solution would be a while-loop:
var i = 5
while num/i > 0 {
print(i)
i *= 5
}
but the advantage of the first solution is that the scope of the loop variable is limited to the loop body, and that the loop variable is a constant.
Swift 3.1 will provide a prefix(while:) method for sequences,
and then the helper function is no longer necessary:
let num = 1000
for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) {
print(i)
}
All of above solutions are "equivalent" to the given C loop.
However, they all can crash if num is close to Int.max
and $0 * 5 overflows. If that is an issue then you have to check
if $0 * 5 fits in the integer range before doing the multiplication.
Actually that makes the loop simpler – at least if we assume that
num >= 5 so that the loop is executed at least once:
for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) {
print(i)
}
For completeness: an alternative to the while loop approach is using an AnyIterator:
let num = 1000
var i = 5
for i in AnyIterator<Int>({
return i <= num ? { defer { i *= 5 }; return i }() : nil
}) {
// note that we choose to shadow the external i variable name,
// such that any access to i within this loop will only refer
// to the loop local immutable variable i.
print(i)
// e.g. i += 1 not legal, i refers to a constant here!
} /* 5
25
125
625 */
This method suffers from the same drawback as the while loop in that the loop "external" i variable persists outside and after the scope of the loop block. This external i variable is not, however, the i variable that is accessible within the loop body, as we let the loop body variable i shadow the external one, limiting access to i within the body to the immutable, temporary (loop scope local) one.

SWIFT IF ELSE and Modulo

In Swift, I need to create a simple for-condition-increment loop with all the multiples of 3 from 3-100. So far I have:
var multiplesOfThree: [String] = []
for var counter = 0; counter < 30; ++counter {
multiplesOfThree.append("0")
if counter == 3 {
multiplesOfThree.append("3")
} else if counter == 6 {
multiplesOfThree.append("6")
} else if counter == 9 {
multiplesOfThree.append("9")
}
println("Adding \(multiplesOfThree[counter]) to the Array.")
}
I would like to replace all the if and else if statements with something like:
if (index %3 == 0)
but I’m not sure what the proper syntax would be? Also, if I have a single IF statement do I need a .append line to add to the Array?
You are very much on the right track. A few notes:
Swift provides a more concise way to iterate over a fixed number of integers using the ..< operator (an open range operator).
Your if statement with the modulus operator is exactly correct
To make a string from an Int you can use \(expression) inside a string. This is called String Interpolation
Here is the working code:
var multiplesOfThree: [String] = []
for test in 0..<100 {
if (test % 3 == 0) {
multiplesOfThree.append("\(test)")
}
}
However, there is no reason to iterate over every number. You can simply continue to add 3 until you reach your max:
var multiplesOfThree: [String] = []
var multiple = 0
while multiple < 100 {
multiplesOfThree.append("\(multiple)")
multiple += 3
}
As rickster pointed out in the comments, you can also do this in a more concise way using a Strided Range with the by method:
var multiplesOfThree: [String] = []
for multiple in stride(from: 0, to: 100, by: 3) {
multiplesOfThree.append("\(multiple)")
}
Getting even more advanced, you can use the map function to do this all in one line. The map method lets you apply a transform on every element in an array:
let multiplesOfThree = Array(map(stride(from: 0, to: 100, by: 3), { "\($0)" }))
Note: To understand this final code, you will need to understand the syntax around closures well.