Fibonacci Sequence using iterator protocol

Deekshith Bellare
Sep 8, 2018 · 2 min read

Iterator protocol in Swift is the driving force behind the for-in loop of any sequence. Any type confirming to Sequence protocol such as an Array should provide its own iterator.
So the implementation of the Fibonacci sequence would look like this

class FibonacciSequence:Sequence {
func makeIterator() -> FibonacciIterator {
FibonacciIterator()
}
}

Iterator keeps track of its iteration process and returns one element at a time as it advances through the sequence. Iterator has to implement next() function which returns the next element of the sequence.

struct FibonacciIterator:IteratorProtocol {

var (firstNumber, secondNumber) = (0, 1)
mutating func next() -> Int? {
(firstNumber, secondNumber) =
(secondNumber, firstNumber + secondNumber)
return firstNumber
}
}

next() function calculates the next step or next number in the Fibonacci sequence.
Now we can use FibonacciSequence in the for-in loop

let fibonacciSequence = FibonacciSequence().prefix(5)
for number in fibonacciSequence {
print(number)
}
//prints 1 1 2 3 5

Notice that FibonacciIterator is infinite iterator and has no termination condition. Sequence can be terminated with the condition such as maximum length of the sequence or any other termination condition.

For example, we could generate Fibonacci numbers up to 50 with the following code

let fibonacciSequence = FibonacciSequence().prefix { $0 < 50 }

If you are implementing an iterator and wants to control termination of sequence at the iterator level, add a termination condition

struct FibonacciIterator: IteratorProtocol {  var (firstNumber, secondNumber) = (0, 1)  var maxLength:Int = 0
var currentLength:Int = 0
init(maxLength:Int) {
self.maxLength = maxLength
}
mutating func next() -> Int? {
guard currentLength < maxLength else {
return nil
}
(firstNumber, secondNumber) =
(secondNumber, firstNumber + secondNumber)
currentLength += 1
return firstNumber
}
}

Above FibonacciIterator takes the maximum number in its initializer and returns nil after the maximum number of iterations reached.

let fibonacciSequence = AnySequence{ FibonacciIterator(maxLength:6)}for number in fibonacciSequence {
print(number)
}
//prints 1,1,2,3,5,8

Implementing custom sequence with the help of the iterator protocol is useful especially when we want to implement lazy loading.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade