Swift is widely known and loved by programmers for different things. One of these are it’s Collections and the Sequence type that comes with it. Sequence is not just for Swift standard library collections, however. It can also, as a protocol, be applied to really any struct or class that wants to behave like a collection in Swift and implement the Sequence methods.
The most commonly used thing Sequence brings us is the abilty to use for-in loops.
This allows us to write things like:
Without Sequence, we’d end up writing something like this:
So Sequence brings us for-in loops. But it turns out these are really at the root of everything we get with the Sequence type. Here are some of it’s more frequently used functions:
- func dropFirst(_:)
- func dropLast(_:)
- func filter(_:)
- func forEach(_:)
- func map(_:)
- func split(_:omittingEmptySubsequences:whereSeparator:)
- func contains(where:)
- func first(where:)
- func reduce(::)
- func reversed()
- func sorted(by:)
Looking at these.. you can implement all of these using a for-in loop. Consider the implementation for contains(:).
It pretty uncomplicated stuff right? So, if you wanted to create your own custom collection and get the power of Sequence and all these useful methods. How do you do it? It’s fundamentally based in allowing the iteration of a for-in loop.
Let’s look at doing this for a pretty basic data structure, the linked list. So, a linked list is a set of instances that each have a reference to the next element in the set.
Fundamentally, to implement a linked list, you’re going to need a representation of a link and something to represent the list. If we want to add Sequence type functionality… we’ll create both those classes as we would typically, but the list itself needs to implement both the Sequence and IteratorProtocol protocols. All we need to implement here is the next() function.
Notably, with this linked list example.. we don’t get the first element, or the head, printed. This is down to the fact that our implementation of next(), when called for the first time returns the second link.. which we then print. This could be solved by introducing a subclass of Link to represent the head and then to instantiate the LinkedList with this.
Summing it Up
So, the Sequence protocol is pretty simple and easy to add to a custom collection object. It brings a suite of great functions for your use. What you’re essentially setting up when you implement the Sequence and IteratorProtocol protocols is the instruction for enumeration.. which is the functionality at the core of all functions provided by Sequence. Well done Swift writers!