control structures

New updates to Swift bring interesting changes to control structures. The most notable of these changes are the removal of C-based loops and increment / decrement symbols (eg., ++ / --). If you’re in the process of learning Swift, these changes may come as a surprise. In this essay, we’ll review the loop control structure and will explore some alternate iteration techniques with Swift.


C-LOOP BASICS

The C-style loop is a classic control structure found in every C-based language. Also called a for-loop, examples can be expressed in Java, Javascript, Objective-C and C#. Consider the following:

var numberList: Array<Int> = [8, 2, 10, 7, 5]

//deprecated C-loop syntax
for var index = 0; index < numberList.count; index++ {
    print(numberList[index])
}

As shown, the for-loop consists of three parts. The first part sets the variable assignment while the second statement provides the terminating condition. The final statement updates the loop variable - assuming the terminating condition hasn’t been met. When applied, this classic / cross-platform technique has been used to build countless user interfaces, algorithms and backend systems.


THE WHILE LOOP

Even though the C-loop fades away in Swift, there are other techniques that meet and, in some cases, exceed this classic tool. First, let’s consider the while-loop:

var numberList: Array<Int> = [8, 2, 10, 7, 5]
var index: Int = 0

//prints 8, 2, 10, 7, 5
while index < numberList.endIndex {
    numberList[index]
    index += 1
}

What’s nice about the while-loop is that it is a widely adopted format. If you used this technique in a technical interview, others would have little problem following your logic. With my project, I often use the while-loop with other Swift-specific syntax.


FAST ENUMERATION

Beyond basic loops, let’s consider the common task of iterating through a collection. The idea of fast enumeration is common but the syntax varies, dependent on programming language. Here are some Swift-specific examples:

var numberList: Array<Int> = [8, 2, 10, 7, 5]

//loop with half-open operator
for index in 0..<numberList.endIndex {
    print(index)
}

//basic fast enumeration
for item in numberList {
    print(item)
}

//tuple combination - index & value
for (index, value) in numberList.enumerate() {
    print("the index \(index) contains value \(value)..")
}

At first glance, these samples look concise. Using the half-open operator, a loop variable can be initialized to zero or some other value. However, what’s missing is being able to control the loop iteration sequence. This would permit cycling through a collection in reverse or skipping certain indices. With Swift, the built-in reverse function can be applied. As shown, reverse can be used to reverse a character set or collection:

//reversed characters
var example: String = "Swift"
var result = String(someArray.characters.reverse())
print(result)


//reversed collection
var numberList: Array<Int> = [8, 2, 10, 7, 5]
var listResult = Array(numberList.reverse())
print(listResult)

TAKING STRIDES

For finer control, the Strideable protocol can be applied. As the name implies, stride can be used to produce specific results:

var numberList: Array<Int> = [8, 2, 10, 7, 5]

//forward stride enumeration
for index in 0.stride(through: numberList.endIndex - 1, by: 1) {
    print(numberList[index])
}


//forward stride enumeration - by two's
for index in 0.stride(through: numberList.endIndex - 1, by: 2) {
    print(numberList[index])
}


//reverse stride enumeration
for index in (numberList.endIndex - 1).stride(through: 0, by: -1) {
    print(numberList[index])
}

While more verbose, this syntax provides good flexibility. When applied, stride allows one to skip items or iterate through a collection in reverse with a consistent format.

Like this series? Subscribe to the newsletter and receive a free guide on iOS interview tips.