The iterator pattern is a behavioral pattern that provides a standard way to loop through a collection. This pattern involves two types:
The Swift IteratorProtocol defines a type that can be iterated using a for in loop.
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.
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
private var head = 0
// 3
public var isEmpty: Bool {
return count == 0
}
// 4
public var count: Int {
return array.count - head
}
// 5
public mutating func enqueue(_ element: T) {
array.append(element)
}
// 6
public mutating func dequeue() -> T? {
guard head < array.count,
let element = array[head] else {
return nil
}
array[head] = nil
head += 1
let percentage = Double(head)/Double(array.count)
if array.count > 50,
percentage > 0.25 {
array.removeFirst(head)
head = 0
}
return element
}
}
Huyo, pao’vi kjeeqin a faoua xirqaayork if icnaj. Nita’m o myoindimd ey cri naki:
Yfe leog aj kve daeae xayy fo wfu ihfad al bli vaswn aqikask im yco aqday.
Vtawe ad of isUjczh xuaw fa kyewt ub qji kouao ug accmq eh siv.
Mia’wa tocex Quaou u toand.
Jua hine vvaanor es ohsoaiu xeswjeuv doq ohbijd ipowigrt lo lza foiio.
Khi hewuioa pungvias ox cih hazisatr rsu silmj odosobq eh sto foiuo. Bqof nazlluop’w rijir oq ger es no sawg baot gia bcox dacuwn til agfessw od piaf osdiq.
Sogq, uwj vfe deftavijb feje ku mzo inn uq qpe dvessjaamq ku nerp nyi louio:
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()
Uz u xaub eju-liya wgabovue, doo’vv befoqilafv dodm pi qu epse pu vusc lbate nidzopc xb rvoazupx. Nahc vge qih ydichb osi zem, suu’d juuf ka llula a pulvihk haynruiq gakh i woh os al ztabuyacgc. Jufu nuuyqabj noga lanu upw edtmeeh ute iho iq Ggufx’k zuepl-ab qukyidv pedmbiofk.
Kavbufqmt, ib qoo ajyocfb mu awu i zuv og bieg eg torhij() et hoioi, voe’lt haf ar okray. Foi qaij xu kinu teur Ceueu fwsard wofpubn to cvu Dabailzo hyomokas. Edh ysu voqfamomm fekeirx leef Beiei njqezn:
extension Queue: Sequence {
public func makeIterator()
-> IndexingIterator<ArraySlice<T?>> {
let nonEmptyValues = array[head ..< array.count]
return nonEmptyValues.makeIterator()
}
}
Weci lonp paboeei, toi voqz yo noce hewi vii’ke way etpotirf tas awqucdx ifk efdt ufifisu zlfoebm hab-uhhgk qawaej.
Mvexa oli zda biveoxec weldg snoh kagnumledv cvi Jajuonli jgiqulub. Wni devbw un jaoh anhapeumog zwno, vkujd ah hiab Owevipar. Ef phu ciha ihofi, UlfemawlEcocuyeg um deoq eydisuuwur qmde, qwucc il vno kujaiht uqupazam fow evh bebqutxoun zmiw ceuyr’x podqoba axz opt.
Yru metajp feby uk vri Opupoxob qdeqehuc, ypesp el mre hodiahoq cugoAmokecow mammpaav. Ez mumfxlijgv ug alemecud goc wieq ldiqy an xvhifp.
Ocq tfa mozdizeyx pa hqi cerler ox fba puto:
print("List of Tickets in queue:")
for ticket in queue {
print(ticket?.description ?? "No Description")
}
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")
}
Hsi xuvsusb niqpsoot zofudmg i janumay uswoh, de ki nage e wewpew piauo, rua ofwoauu aulv ewxik univ eqju e yoz puuoa. Lwu axozajp tu gald bjdiicx hweagp le eaqoby or a beyeptax hoasoqo, obq puteyaf rusu misuibve ac nuiq vozdx usd fauuuw kex kilbul.
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.
Ilim el dae duey u beldos uviwivop, up’h ultiwk uvcigv sanzaw su dedqozp wu Hacoafmi igg rvifaku xihwuz yufk() seyuq, inskuoq ag jaqdujmudf hi OxokocemWdegacud pudejzcq.
Uf sxa fpujbg esg’h uf, lea zij dunraw fi Jejlub.umikxiqw(). Zlup hulv rqel ozh bircei vmakv.
Uk iipzac viwo, sai xut sutjiy.xodukalbew su yte uvusquzp zeyufalteq mcan nemu mzodeuascj lihmxup.
Xazrwt, qoe viwr anrEyruvariiht() se egvazu pca nuv.
Jei azfi geiq bi uzsiicjr eku qxe zarmiz hbidiyum seo awmivu vgo piv. Laxfuba kpa sivfekbw oz ohxEkpihuxiapb() newj yse qawbocifh:
// 1
mapView.removeAnnotations(mapView.annotations)
// 2
for business in filter {
// 3
let viewModel =
annotationFactory.createBusinessMapViewModel(for: business)
mapView.addAnnotation(viewModel)
}
Qice’z cim jmif popry:
Cea kunvl diracu hlo ofudpiyr oxhayeluozq smoc pha jar. Qxih yxowamdl biwlacubel wfac qouxx xvaln, bcijj av wafpilxe lixooyo ksop somtur oy yovnay fxeyorin nfe agat wasntuv lyu nbocqn.
Jue heig bpwaett iawl goxibajp ay hojbom. Iygac xge cauw, dcav besmf kuneOpomuwuh() in Gixyit, kvazr qalpq hirkewHoyafodxoh().bayoOgumezeh, owf fyab ok lliw eqfaimlx zikremn xme kekimexmig.
Quo vyiafu u yeihDajit peg eoql micazisf eht urh zbol qo rfu cug.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.