How to loop in Swift
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.
Debug 10x faster with Proxyman: Your ultimate tool to capture HTTPs requests/ responses, natively built for your iPhone and macOS. Special deal for Black Friday: Get 30% off for all Proxyman licenses with code “BLACKFRIDAY2024”.
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.
Debug 10x faster with Proxyman: Your ultimate tool to capture HTTPs requests/ responses, natively built for your iPhone and macOS. Special deal for Black Friday: Get 30% off for all Proxyman licenses with code “BLACKFRIDAY2024”.
Related Resources
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 ShareHow 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.