# 13 Iterator Pattern Written by Jay Strawn

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

The iterator pattern is a behavioral pattern that provides a standard way to loop through a collection. This pattern involves two types:

1. The Swift `IteratorProtocol` defines a type that can be iterated using a `for in` loop.

2. The iterator object is the type you want to make iterable. Instead of conforming to `IteratorProtocol` directly, however, you can conform to `Sequence`, which itself conforms to `IteratorProtocol`. By doing so, you’ll get many higher-order functions, including `map`, `filter` and more, for free.

What does “for free” mean? It means these useful built-in functions can be used on any object that conforms to `Sequence`, which can save you from writing your own sorting, splitting and comparing algorithms.

## When should you use it?

Use the iterator pattern when you have a type that holds onto a group of objects, and you want to make them iterable using a standard `for in` syntax.

## Playground example

Open IntermediateDesignPattern.xcworkspace in the Starter directory, or continue from your own playground workspace from the last chapter, then open the Iterator page.

``````import Foundation

// 1
public struct Queue<T> {
private var array: [T?] = []

// 2

// 3
public var isEmpty: Bool {
return count == 0
}

// 4
public var count: Int {
}

// 5
public mutating func enqueue(_ element: T) {
array.append(element)
}

// 6
public mutating func dequeue() -> T? {
let element = array[head] else {
return nil
}

if array.count > 50,
percentage > 0.25 {
}

return element
}
}
``````
``````public struct Ticket {
var description: String
var priority: PriorityType

enum PriorityType {
case low
case medium
case high
}

init(description: String, priority: PriorityType) {
self.description = description
self.priority = priority
}
}

var queue = Queue<Ticket>()
queue.enqueue(Ticket(
description: "Wireframe Tinder for dogs app",
priority: .low))
queue.enqueue(Ticket(
description: "Set up 4k monitor for Josh",
priority: .medium))
queue.enqueue(Ticket(
description: "There is smoke coming out of my laptop",
priority: .high))
queue.enqueue(Ticket(
description: "Put googly eyes on the Roomba",
priority: .low))
queue.dequeue()
``````
``````extension Queue: Sequence {
public func makeIterator()
-> IndexingIterator<ArraySlice<T?>> {

let nonEmptyValues = array[head ..< array.count]
return nonEmptyValues.makeIterator()
}
}
``````
``````print("List of Tickets in queue:")
for ticket in queue {
print(ticket?.description ?? "No Description")
}
``````
``````extension Ticket {
var sortIndex : Int {
switch self.priority {
case .low:
return 0
case .medium:
return 1
case .high:
return 2
}
}
}
``````
``````let sortedTickets = queue.sorted {
\$0!.sortIndex > (\$1?.sortIndex)!
}
var sortedQueue = Queue<Ticket>()

for ticket in sortedTickets {
sortedQueue.enqueue(ticket!)
}

print("\n")
print("Tickets sorted by priority:")
for ticket in sortedQueue {
print(ticket?.description ?? "No Description")
}
``````

## What should you be careful about?

There is a protocol named `IteratorProtocol`, which allows you to customize how your object is iterated. You simply implement a `next()` method that returns the next object in the iteration. However, you’ll probably never need to conform to `IteratorProtocol` directly.

## Tutorial project

You’ll continue building onto Coffee Quest from the previous chapter. You’ll finally be adding functionality to the switch in the upper-right corner!

``````public struct Filter {
public let filter: (Business) -> Bool

public static func identity() -> Filter {
return Filter(filter: { _ in return true }, businesses: [])
}

public static func starRating(
atLeast starRating: Double) -> Filter {
return Filter(filter: { \$0.rating >= starRating },
}

}
}

extension Filter: Sequence {

public func makeIterator() -> IndexingIterator<[Business]> {
}
}
``````
``````private var filter = Filter.identity()
``````
``````self.filter.businesses = businesses
``````
``````if sender.isOn {
// 1
filter = Filter.starRating(atLeast: 4.0)
} else {
// 2
filter = Filter.identity()
}
// 3

// 4
``````
``````// 1
mapView.removeAnnotations(mapView.annotations)

// 2

// 3
let viewModel =
}
``````

## Key points

You learned about the iterator pattern in this chapter. Here are its key points:

## Where to go from here?

You’ve added a lot of great functionality to Coffee Question over the last few chapters! However, there’s still many more features you could add:

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below: