How to loop in Swift

⋅ 5 min read ⋅ Swift Array Control Flow

Table of Contents

Swift provides a variety of ways to loop. Today, we will visit all of them based on the situation that you might need them.

Loop over a collection

This is the most common task in my day to day work. Swift provides for-in loop for this kind of job. You use the for-in loop to iterate over a sequence, such as items in an array.

This example uses a for-in loop to iterate over the subviews and set their translatesAutoresizingMaskIntoConstraints to false.

let subviews = [subview1, subview2, subview3, subview4]

for subview in subviews {
subview.translatesAutoresizingMaskIntoConstraints = false
}

There also another variation of looping over a collection, that is forEach(_:). It is a functional style of the loop. It calls the given closure on each element in the sequence in the same order as a for-in loop.

Our for-in code can be written with forEach(_:) like the following.

let subviews = [subview1, subview2, subview3, subview4]

subviews.forEach { (subview) in
subview.translatesAutoresizingMaskIntoConstraints = false
}

Since forEach(_:) has a parameter as a closure that takes an element of the sequence as a parameter, you can make your statement more readable by giving its name.

let subviews = [subview1, subview2, subview3, subview4]

let prepareForAutoLayout = { (view: UIView) in
view.translatesAutoresizingMaskIntoConstraints = false
}

subviews.forEach(prepareForAutoLayout)

Or, if you use it in many places, you can even make it to a function.

func prepareForAutoLayout(view: UIView) {
view.translatesAutoresizingMaskIntoConstraints = false
}

let subviews = [subview1, subview2, subview3, subview4]
subviews.forEach(prepareForAutoLayout)

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Loop over a collection with index

If you also want to know the index of an element in a collection, you can retrieve that with the help of .enumerated() method. It will return a sequence of pairs (n, x), where n represents a consecutive integer starting at zero and x represents an element of the sequence.

let names = ["Anna", "Alex", "Brian", "Jack"]
for (index, name) in names.enumerated() {
print("\(index + 1). \(name)")
}
// 1. Anna
// 2. Alex
// 3. Brian
// 4. Jack

Loop over a dictionary

You can also iterate over a dictionary to access its key-value pairs. Each item in the dictionary is returned as a (key, value) tuple when the dictionary is iterated.

The responseMessages variable is inferred to have type [Int: String]. The Key type of the dictionary is Int, and the Value type of the dictionary is String. We get a tuple of type (key: Int, value: String) and assign it to message variable for each iteration.

var responseMessages = [200: "OK",
403: "Access forbidden",
404: "File not found",
500: "Internal server error"]
for message in responseMessages {
print("\(message.key): \(message.value)")
}
// 403: Access forbidden
// 404: File not found
// 200: OK
// 500: Internal server error

You can also decompose the tuple's members as explicitly named constants for use within the body of the for-in loop. The following is the same code, but this time we map the first tuple key into a constant called code, and the second tuple value into a constant called meaning.

var responseMessages = [200: "OK",
403: "Access forbidden",
404: "File not found",
500: "Internal server error"]
for (code, meaning) in responseMessages {
print("\(code): \(meaning)")
}
// 403: Access forbidden
// 404: File not found
// 200: OK
// 500: Internal server error

Loop for a specific number of times

If you want to perform a task multiple times, you can also do that with for-in loop. But this time, instead of iterate over an array, we do it over ranges of numbers.

This example prints the number 1, 2, 3, 4, and 5

for index in 1...5 {
print("\(index)")
}
// 1
// 2
// 3
// 4
// 5

In the above example, we use the closed range operator (a...b), which defines a range that runs from 1 to 5, inclusive (include 5). If you don't want to include the last value, you can use what Swift called the half-open range operator (a..<b).

This example prints the list of name by using i as array index. We don't want the last value otherwise we will get Index out of range error.

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("\(i + 1). \(names[i])")
}
// 1. Anna
// 2. Alex
// 3. Brian
// 4. Jack

As you can see, Swift offers several range operators to work with for loop. We can also use this in our collections to get the desired results.

Loop over the first n elements of a collection

We use half-open range on a collection to limit the number of the loop.

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[0..<2] {
print(name)
}
// Anna
// Alex

Loop over a collection skipping the first n elements

We use one-side range on a collection to omit the value from one side of the range operator.

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[2...] {
print(name)
}
// Brian
// Jack

Loop while a condition is met

Most programming languages have while and do-while to perform a statement while a condition is true, and break the loop if a condition becomes false. In Swift, they are named while and repeat-while.

The only difference between do-while and repeat-while in Swift is the name.

A while loop starts by evaluating a single condition. If the condition is true, a set of statements is repeated until the condition becomes false.

while condition {
// statement that affects the condition
}

The repeat-while loop performs a statement first before considering the loop’s condition. It then continues to repeat the loop until the condition is false. So repeat-while will make sure the statement is executed at least once.

repeat {
// statement that affects the condition
} while condition

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Read more article about Swift, Array, Control Flow, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
How to fix "Build input file cannot be found" error in Xcode

There might be several reasons that cause this error. I will share one solution that fixes the one that happened to me the most.

Next
How to use DateFormatter in Swift

Learn how to use this expensive DateFormatter.

← Home