Swift Sequences

Before diving into Swift Sequences, let’s see a strange behavior.

In other words, when requesting an element that doesn’t exist, why arrays crash whereas dictionaries don’t?

Arrays and dictionaries are two base collections provided by the Swift standard library. We can access those collections elements through the [] notation, also known as subscript. Let’s see how those subscripts are defined.

What’s interesting is that arrays have a non optional return type. Subscript can’t throw errors so there is no alternatives other than a fatalError if we request an index that doesn’t exist.

For dictionaries, on the other hand, an optional Value is returned, which allows to gracefully return nil if the index doesn’t exist.

We can adopt dictionaries safer approach by overloading the arrays subscript — we can’t override them. Adding an external name to the parameter is enough.

We saw how we can create a new accessor to the elements of an array, but can we do the same with a homemade collection?

Homemade collection

Internally, this ‘collection’ is based on an array. This is an implementation detail for the simplicity of the example. We could have used a linked list as in this excellent article by Austin Zheng.

Creating a subscript on our collection is very easy, we can even reuse the array’s extension we made earlier.

An example in practice :

Great! But does that make our type a collection, as Swift defines it?

Sequences

When it comes to manipulating sets, the most abstract notion given by the standard library is the Sequence, defined as

A type that can be iterated with a `for`…`in` loop.

In its state, our type isn’t a Sequence. To become one, it has to conform to the SequenceType protocol.

We need to implement a method that returns a generator. A generator is a type that will encapsulate our sequence and store the progression of the elements enumeration. It’s once again a protocol and here is what it requires

Every time the next method is called, the generator will return the next element of the sequence or nil if we have been through the whole sequence — it isn’t required as sequences can be infinite.

Here is a way to define a generator in our case :

Our Section can conform to SequenceType…

…and we’ll be able to iterate through its elements :

The for … in notation is just a shortcut for the notation above it. Even if we don’t see it, when using a for … in loop, a generator for our sequence is created and its next method is called until the sequence is over or until we break out of the loop.

Gift

Is that all? No! By conforming to SequenceType we also get methods for free, here is some of them.

We get the min, max & sort methods because the elements of our sequence, String in our case, are Comparable. Contains is available thanks to our elements being Equatable.

And for functional programming fans, filter, map and reduce are also given.

We advanced in our researches on sequences. In the next part, we’ll see collections and we’ll finally understand why arrays and dictionaries behave so differently!

Like what you read? Give Greg Lhotellier a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.