Home Articles

Flavours of for loop in Swift

Let us deep dive understood the for-In, forEach, for-In-Enumerated in Swift and how it is different from other languages and why?

Swift provides us with multiple ways to loop through items in a collection. They are:


for language in languages {
    print(language)  
}

languages.forEach { (language) in
    print("Language", language)  
}

for (index, element) in languages.enumerated() {
    print("Index:", index, "Language:", element)  
}

1. for-In


for value in range {  
    // statements  
}

In many programming languages, the for-in loop is called forEach. Standard loop statement in other languages uses this format:


for(i = 0; i < n; i++) {    
    // statements  
}

Important

The c-style for-loops are no longer supported from swift 3

C-style For loop error in Swift

In Swift it's different, the rationale behind for-in syntax in Swift is that it can be used to loop over ranges, sequences, iterators, collections and even strings. All with the same syntax:


let languages = ["English", "Tamil", "German"]

for i in 0 ..< languages.count {  
    print("Language \(i+1):", languages[i])  
}

// Output:
Language 1: English  
Language 2: Tamil  
Language 3: German

In Swift, object types like arrays, dictionaries and sets are known as collections. Any collection can be iterated with a for-in loop.

for a dictionary, we can iterate like this:


let languagesDict = [  
    "England":"English", "Germany":"German", "Mexico":"Spanish"  
]

for (country, language) in languagesDict {  
    print("The \(country)'s Language is \(language)")  
}

// Output:
The Germany's Language is German  
The Mexico's Language is Spanish  
The England's Language is English**

Swift also provides two range operators lowerBound...upperBound and lowerBound..<upperBound as shortcuts for expressing a range of values.


for i in 0...5 {  
    print(i)  
}

// Output:  
0  
1  
2  
3  
4  
5

for i in 0..<5 {  
    print(i)  
}

// Output:  
0  
1  
2  
3  
4

Warning

If lowerBound is greater than upperBound, the code will crash

If we want to reverse the range for looping, we can easily achieve that using:


for i in (0...5).reversed() {  
    print(i)      
}

// Output:  
5  
4  
3  
2  
1  
0

Stride

As I mentioned above, C-Style for loops are not supported from swift 3, so how we can get the increment of the counter variable i.e. i++

It can be achieved using stride, it helps us to move from one value to another using any incremental value and we can also specify whether the upper bound is inclusive or exclusive.


for i in stride(from: 0, to: 10, by: 2) {  
    print(i)  
}

// Output:  
0  
2  
4  
6  
8

there is also another type of stride in swift:


for i in stride(from: 0, through: 10, by: 2) {  
    print(i)  
}

// Output:  
0  
2  
4  
6  
8  
10

the basic difference is, from-to calculates the element before to but in from-through it takes the through element also into consideration. It's similar to < and <=


func stride<T>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> where T: Strideable

Apple Docs


func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T: Strideable

Apple Docs

2. forEach


languages.forEach { (language) in
    print("Language", language)  
}

// Output:  
Language English  
Language Tamil  
Language German

Swift provides a dedicated method forEach for a specific usecase, unlike the above forIn, this method cant break the loop part way (at some point). It has to loop over each item in the sequence.

This helps people reading your code to figure out your intent, that you want to act on all items and won’t stop in the middle.

Note

  • break ends the loop’s execution immediately and transfers control to the code after the loop’s closing brace (}). No further code from the current iteration of the loop is executed, and no further iterations of the loop are started.
  • continue statement tells a loop to stop what it’s doing and start again at the beginning of the next iteration through the loop. It says “I am done with the current loop iteration” without leaving the loop altogether.

For example:


var evenNumbers = [Int]()

for number in (0...100) {  
    guard evenNumbers.count < 10 else {  
        break  
    }  
  
    guard number % 2 == 0 else {  
        continue  
    }

    evenNumbers.append(number)  
}

print(evenNumbers)  
  
// Output: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

same cannot be achieved in forEach with break and continue, so we need something like this:


let evenNumbers = (0...100)
    .filter { number -> Bool in  
        return number % 2 == 0  
    }
    .prefix(10)

print(evenNumbers)  
  
// Output: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

3. for-In-Enumerated


for (index, element) in languages.enumerated() {  
    print("Index:", index, "Language:", element)  
}

// Output:  
Index: 0 Language: English  
Index: 1 Language: Tamil  
Index: 2 Language: German

This swift loop iterates over each of the item by also telling the index of it. If we need to iterate over the elements and need their index also, then for-in-enumerated is the perfect loop for us.

Nested For Loops

Also, we can use a for loop inside another for loop


var nationals = ["Brits", "Spain", "Italy"]  
var languages = ["English", "Spanish", "Italian"]

for i in 0 ..< nationals.count {  
    var string = "\(nationals[i]) speaks"
    for _ in 0 ..< languages.count {  
        string += "\(languages[i])"  
    }
    
    print(string)  
}

// Output:  
Brits speaks English English English  
Spain speaks Spanish Spanish Spanish  
Italy speaks Italian Italian Italian

While

A while loop performs a set of statements until a condition becomes false.


while condition {  
    // statements  
}

var index = 0  
while index < languages.count {  
    print(languages[index])  
    index += 1  
}

// Output:  
English  
Tamil  
German

Repeat

Repeat while loop is similar to do while loop in other languages.

It is similar to the above while loop in Swift. But, the major difference is that, this loop evaluates the condition after running the statements (at the end).

It’ll always run at least once


repeat {  
    // statements  
} while condition

var index = 0  
repeat {  
    print(languages[index])  
    index += 1  
} while index < languages.count

// Output:  
English  
Tamil  
German

Both while and repeat are best used in loops where the number of steps are unknown.

The entire playground can be found here

This is a free third party commenting service we are using for you, which needs you to sign in to post a comment, but the good bit is you can stay anonymous while commenting.