Learn the iterator design pattern by using some custom sequences, in accordance with IteratorProtocol from Swift Standard Library.
This time I will focus on iterator design pattern. The pattern is widely used in the Swift standard library. There are protocols that give you support if you need to create an iterator, but honestly: I have never implemented this pattern directly. 😅
The truth is that it's probably in 99% of usage cases you never have to deal with this pattern because it's incredible support for iterators built into Swift. Always use sequences, arrays, dictionaries instead of directly implementing this pattern, but it's good to know how things work under the hood, right? 🙃
What is the iterator desin pattern?
As the name suggests, the pattern makes it possible to iterate a collection of elements. Here is the definition of the four-gang gang:
Give a way to access the items in a single object in order without exposing the underlying representation.
Long story short iterator gives you an interface that allows you to iterate collections no matter how they are implemented in the background. Here is a quick example of the theory above using a strict iterator.
As you can see, there are two main protocols and a very simple implementation for both. Our
DataArray class now works as a true selection, the underlying elements can be iterated by using a loop. Let's dig the theory and implement the example from above using genuine Swift standard library components. 😉
Matched sequences in Swift
Swift has a built-in sequence protocol that helps you create iterators. Implementing your own sequence in Swift is about hiding your underlying data structure by creating a custom iterator object. You only need to save the current index and return your next item accordingly every time the next function is called. 😛
So the sequence protocol is a generic counterpart to our customizable iterable protocol used in the first example. IteratorProtocol is something that the string iterator protocol used before, but more Swiftish and of course more generic.
So this is great. Finally, you know how to create a custom sequence. Which is good if you want to hide your data structure and provide a generic iterable interface. Imagine what would happen if you were to start using a dictionary instead of a matrix to save named emojis without an iterator that breaks them. 🤔
Now the case is that there is an extra super useful thing in the Swift standard library that I want to talk about. That's right, an abstract level up and here we are:
Custom Collections in Swift
Collections are one step beyond sequences. Elements inside of them can be reached by subscription they also define both startIndex and endIndex, plus individual items in a collection can be accessed several times. Sounds good? 👍
Sometimes it may be useful to create a custom collection type. For example, if you want to eliminate optional values. Imagine a categorized favorite mechanism, for each category you want a variety of favorites, so you have to handle empty and non-existent things. With a custom collection, you can hide the extra code in your custom data structure and provide a clean interface for the rest of your app. 😍
I know, this is a very stupid example, but it demonstrates why collections are more advanced compared to pure sequences. Also in the links below are good demonstrations of well-written collections. Feel free to learn more about these superprotocols and custom data types hidden (not so deep) inside the Swift standard library. 🤐