Zip 3
In the Swift Standard Library, you’ll find a convenient free function called zip
which will interlace any two sequences you give it.
This print out:
Sometimes though, you need to interlace three sequences. Behold! Zip3, an implementation closely patterned on the Standard Library’s implementation of zip
: formatting, naming conventions, etc.
The function itself is extremely short. It just takes three sequences of possibly three separate types and returns some type that is generic over those same three sequence types. We will overload the Standard Library’s zip
function and the third parameter will differentiate this implementation so the compiler will know which to use.
One admirable trait of the Standard Library’s implementation is the way it breaks its task into most dirt simple parts. The return type of the zip
function is a Zip3Sequence
struct. It is initialized with the three sequences which are stored as properties. Consequently the types of these three sequences are associated with the aliases Sequence1
, Sequence2
, and Sequence3
.
Eventually, we want Zip3Sequence
to conform to Sequence
. As a prerequisite, it needs to define a type conforming to IteratorProtocol
that it will use as the return type of the makeIterator
function. We’ll nest this definition within the Zip3Sequence
itself since it is specific to that type.
This Iterator
struct holds the three iterators created by the three sequences of the Zip3Sequence
respectively and a flag indicating whether the iterator should at last return nil
.
Of course Zip3Sequence.Iterator
does not yet conform to IteratorProtocol
. It must implement the next() -> Element?
function. This can be done within an extension on Zip3Sequence.Iterator
.
The return type of next()
is an optional Element
which is a tuple of the Element
types of the three underlying sequence iterators. This the type that each successive iteration of the sequence will yield, a three-part tuple of the three corresponding elements from the three underlying sequences. As long as all three return elements, the sequence continues. Once any one of them returns nil, the whole sequence ends. That’s all that is needed for Zip3Sequence.Iterator
to conform to IteratorProtocol
. Now that it does, Zip3Sequence
can finally conform to Sequence
.
All Zip3Sequence
needs to do is implement makeIterator()
which will create an iterator of the type it just defined and return it. The iterator is initialized with freshly created iterators from the three underlying sequences.
The code for zip3 is available a gist. Enjoy!
How to update your Cocoapod