For Loops

For loops, in Swift, work exactly as they do in Python. We provide a Sequence, and the loop will iterate through it. The most common sequences you will see are lists, dictionaries, and ranges. In addition to the sequence, we provide an identifier, which is bound to a new element per iteration.

The syntax is: for <identifier> in <sequence> { ... }

var myIntegers = [0, 1, 2]
for integer in myIntegers {
    print(integer)
}
// 0
// 1
// 2

If you want to iterate through a range of numbers you have two methods. If you want to iterate at an increment of one, I highly suggest using a range.

Ranges

If you want to do something more complex–say you want to iterate backwards through a sequence, want to increment by 2s, or iterate over a sequence of floats–you may want to try strides. You do not need to understand the Stride protocol for this unless you are doing something extra cool. For the most part, you can use the functions stride(from: _, to: _, by: _) or stride(from: _, through: _, by: _). The distinction between these two functions is that from->to by is a range that excludes the end (to). In contrast, from -> through by may include the end (through). The uncertainty here lies from the fact that you can input a by parameter that does not evenly divide through - from. For example, stride(from: 0, to: 10, by: 3) would represent 0, 3, 6, 9.

for number in stride(from: 0, to: 0.5, by: 0.1) {
    print(number)
}
// 0
// 0.1
// 0.2
// 0.3
// 0.4

Be careful when using this function to be consistent with your types because it is a generic function.

Behind the Scenes

This is an advanced topic as it is basically an exercise in protocols with associated types.

Protocols With Associated Types

Anyways, for those that are interested in creating their own sequences or strides... I have attached the source code below. Be warned, there will be wonderful documentation, but very scary keywords.

You'll note that the Stride protocol does not implement sequence at all! Instead, the Swift developers married the two PATs with a separate Generic class. This illustrates the importance of PATs! You may think "Why didn't they just create a Generic this is so extra?". The beauty here is that they were able to create vastly different implementations of sequences and avoided any issues of subclassing. In fact, they didn't use classes at all! Swift loves being functional and PATs is one of the ways it manages to do so.

Last updated