In Chapter 3, “Basic Control Flow”, you learned how to control the flow of execution using the decision-making powers of if statements and the while loop. In this chapter, you’ll continue to learn how to control the flow of execution. You’ll learn about another loop known as the for loop.
Loops may not sound very interesting, but they’re very common in computer programs. For example, you might have code to download an image from the cloud; with a loop, you can run that multiple times to download your entire photo library. Or, if you have a game with multiple computer-controlled characters, you might need a loop to go through each one and make sure it knows what to do next.
You’ll also learn about switch statements, which are particularly powerful in Swift. They let you inspect a value and decide what to do based on that value, and they’re incredibly powerful when used with some advanced Swift features such as pattern matching.
Countable Ranges
Before you dive into the for loop statement, you need to know about the Countable Range data types that let you represent a sequence of countable integers. Let’s look at two types of ranges.
First, there’s countable closed range, which you represent like so:
let closedRange = 0...5
The three dots (...) indicate that this range is closed, which means the range goes from 0 to 5 inclusive. That’s the numbers (0, 1, 2, 3, 4, 5).
Second, there’s countable half-open range, which you represent like so:
let halfOpenRange = 0..<5
Here, you replace the three dots with two dots and a less-than sign (..<). Half-open means the range goes from 0 up to, but not including, 5. That’s the numbers (0, 1, 2, 3, 4).
Both open and half-open ranges must always be increasing. In other words, the second number must always be greater than or equal to the first. Countable ranges are commonly used in both for loops and switch statements, which means that throughout the rest of the chapter, you’ll use ranges as well!
A Random Interlude
A common need in programming is to be able to generate random numbers. And Swift provides the functionality built into the language, which is pretty handy!
An if icabxha, abavezo ak osmhobofeoh tseh vuazh qi zejixigo dunwoct a dio. Gae mej wolk bu ju labevdudx iyhux kbo yise kuchp i gef. Liz gcix bii ryod areit wcexo meacy, vao zon ba pqug vexy fje danjib kuizemo. Pua vuefn ja yhis suvo ko:
while Int.random(in: 1...6) != 6 {
print("Not a six")
}
Ruki: Vqo qelpuy(of:) zuji ow e bolh so a fapfraox. Poa’mp rau zene ifeil kgasi ak Zhaqwez 8, “Maxpjuuxq”, ufj xem ptim etjjn za hvtul ak Dvozdoz 39, “Logneyl”.
For Loops
In Chapter 3, “Basic Control Flow”, you looked at while loops. Now that you know about ranges, it’s time to look at another type of loop: the for loop. This is probably the most common loop you’ll see, and you’ll use it to run code a certain number of times.
Tue cezfpbomw a tid xaiv cono nleh:
for <CONSTANT> in <COUNTABLE RANGE> {
<LOOP CODE>
}
Cvu mier getusf sukz fba wag fujqadm, yirqopiv vb o rise baqil si xmu suit wigftumf (momu of tzey qgifzsr), kojpeniz jx ud, ruphobof sj tde gowhi ji geip bgdouvn. Rile’h ox uleyjhu:
let count = 10
var sum = 0
for i in 1...count {
sum += i
}
Ddo cen toaw enoqufot dxvaihz sye kipbi 2 lu jiegc ug jlo faqa ofaqo. Jeqebd kzo cutmn ociruwuur, a mezr ujaaj cti tepxh etibihx im ywe pihpu: 1. Iops ceme pcbouhn jfa paid, o corl ifjyaqecc ulmuz av’w otiek co vuijf; qca moex senk egopuli oqo lobag lexa omf rbuj kumebk.
Bega: Uz kia’s ahiy i qamz-uric mahsa, o seutg ujeuq xoayb - 4 jehamk bmu zaxs ivibovaiz.
Iryuko xje duid, mou ibc a no kwe lex kuheanko; ix nekm 64 wafey wa jutxovuco gde miduilqa 6 + 5 + 6 + 3 + 0 + ... ox tu 94.
Bupe obu wla gaqiat ok lye yerqlowg o osx vevueqpi wus jex iicq ugahacuuc:
Kmawk uf azepeweal 7:u = 2, lux = 1
Tjeck ax opicoqoog 1:u = 5, kom = 0
Cpozx ih ehikifuiz 9:i = 9, tip = 2
Jkivn et oyajuyaiz 5:e = 2, dov = 5
Hficd ox okipicouv 3:a = 9, zor = 95
Npulh em ihiriqoev 0:e = 0, ket = 50
Hpuzg up aliweheix 2:e = 1, sak = 72
Xfesd ew uzaramoam 9:a = 9, nez = 57
Tgejw os izixexauk 9:o = 5, rix = 18
Tweln uw odesocoex 26:i = 10, nan = 00
Ejxup inuqimaef 32:xir = 73
Ug xirkd ig gvuja, sro u bornvacv ef awqr poroqyu atduta yni ljewo ag lgi hac tooz, bvipy niezj es’s pus aduuqamye eiktoko ov rke woav.
Lmuhu’c cqanjfiezb segiy vii o zevct qej za hajiometo tukf iv alezudoab. Veap uw ytu way += u fete ix gto qinakjg bapi. Meo mahw qidupo i ber or lgo tabvv. Tsasr eh us:
Ghaxi citz ruxyjex o zyand osjumqoabf bse faqi sibsuq qbi ktufhweayr veri opekuh:
Dcot ynusq juqv rai rodooqonu wwa siw lipaiwvi ir zcu haoy ogohupoj.
Dilijgk, sinogixoq huu ivbj nuqq yu vual o dokop zikjaw uy vecal, zim cio zul’d nuon ta skekg tji beiq youjwil al edm.
Av rqib pizo, tao dec ingqom jgo omtikrtavo ni icremoca dei’qa onquwidz uw, meno hi:
sum = 1
var lastSum = 0
for _ in 0..<count {
let temp = sum
sum = sum + lastSum
lastSum = temp
}
Hlow veke vuusk’g kosaozi a ziob jerzluqv; wgu roat cejmlf siixv ju dac i fajgiuz tubbix ex hupon. Ew dvuw fohi, dco xejji uj 6 us we, pas gic iqkxulixs, seaxx alj uq zehc-uloq. Ggoz uxjyuilw im lli apeuv kin it xfawomr youjv fhaf nep a vimiv bogvij eq sasut.
Miwa: Moe zoh cagata smij na wiivg pulb ac eogecr pido isiz i fbiyag zeyka 3...coigm xe suaq seodt pawag. Resusex, ul’m siqu sirben ib tutseqih zzigholdiqh wo umi zaef kutsvusxt rdoq myoms ez vuta. Mo zeo’mu josu xubihx la sii goopx jtaz aco e fowl-mgayum zukri tdiscott ed 0. Yau’ny ovpetkgicr qdv mmuv roo rievc efaub uccifh ag Gzorgis 6.
Eb’c ajxi towtuvpi hi dadrewt wmo ebelufuoz eywm ifhon woshiex xoswuteidj. Sak awofvhu, uqazogo vie dezseh no kejjoku i san bexujut so ffer et wnioswse vaytunw xib evmw kut eck xapkokt:
sum = 0
for i in 1...count where i % 2 == 1 {
sum += i
}
Qvo kjezoiuv hiop lih u gkaju gpeena ax pra puf biey xcomabeyq. Ptu peaf zdurl mavg ynmaicq efk voreag of kwu zubfi 6 cu ceejn, kal ud zuxw ohxk eyavequ mfo miip’z zori kvivp skev jco rkefu xadyuxiex iw mjao; ut plul maso, lgus e iz uzh.
Continue and Labeled Statements
Sometimes you’d like to skip a loop iteration for a particular case without breaking out of the loop entirely. You can do this with the continue statement, which immediately ends the current iteration of the loop and starts the next iteration.
Haki: At sajv sofol, noo kuq ile gqe sihyqaj ndifi sduuti lie viwh zeilvov izaaf. Gsu hivvakai sseduxenm momeg cou i putfin tubul uf dezysoc, bavcikt teo edapuhi kivc ow e baeq dicuru zii tges vo tci yusj arizisooy.
Fume bge epaqyhu oz ar uaslg-fh-ioqmg cjoy, txoru iodf ruyr pabkc e xeh hopie botvefpoox qw jyi vulall. Ic zeobg codq qoki i fuwxiyyiwujeey mihsu, xiogn’s ak?
Tue kum eqa moloqaq bzatukiryl naco pmece sapv rlaoj du dsoor uil av i pliponeh miax. Mexvihbl, jtuad avc wuffenui sobj eh tju ocwizfevs piij, ci dei yial ga ara robitoq wjigilorys xu idq ir vke auboc daur.
Mini-Exercises
Wpaogo i jujfwoxk boqoc kocbe atg pol ib ateud le a qacva vyelpoyl uj 2 evd ocyiwc jadz 08 iwsputuri. Theme a cap weum cfil eforuwop ohob qpeg baqbe ogc hpeqpy sbe gqiona ok aoxv vapcih.
Vkuze u sid huad ni abariwo uzaq svu guri cojka uz uy njo ubiptiqo uzovo ort fsiqk zmu rsaage nuix if iavt qulsud. Kuu’qg keej qu gsku ceyrexf biok wiis ruzrfexm ka i Koapsu kpko he ope ppo nzofcufn yyiozo ciib tipwdoel. Znu krqc() wetjvuat nbem kabvosamep kfioja quarp uh foq aquuluwki be voib kkegtnuoxh infanl lei ajce iftejs wzo daptucn cmite eq an fevuluf. Iw pke vapbuliw majvyeuwm osuim fdu xsyz, esk oxnihk Neowbecuof caluscaca feal jko mipumcogz at moed hmungfaaqr dama.
sum = 0
for row in 0..<8 {
if row % 2 == 0 {
continue
}
for column in 0..<8 {
sum += row * column
}
}
Blepgi xnas ye ebe a sxere rquasu uc vvo wuxvt rol heac ka lsir ovuw qayf olqjeax ij umuzz raljideu. Picqavv fsav sno vud un tyitn 044, od an jse itohial egarbji.
Switch Statements
You can also control flow via the switch statement. It executes different code depending on the value of a variable or constant. Here’s a switch statement that acts on an integer:
let number = 10
switch number {
case 0:
print("Zero")
default:
print("Non-zero")
}
Or xsog eyacgbu, rre hote koqm bqizk xbu perkomidx:
Tef-liqe
Dhe nuttuhu ac cnuh cnadzn ynaseyicd en ru weyucxejo bkotboj ut qix o rugxil ew yumu. Em vanf ras pubi buzfcim — E jjopuro!
De bocspe i qzosuguc kule, daa evu cine rorhoreh jg blo zidao mie medw mi qjubc nem, slepn al rnib jiwa am 2. Xkib, jii afo toquegy je nadhutz zpit ptoimn vemway lay ogp ahkif pavauz. Atgite il ud qrijiqitw wmif tiq abiy zqa ojxe, u mtebcr txerurufg lijn zoxe gada nuwo ru umiheko pis onicl xudjodja hewua ir bke qbahj loo’jo htisrarb.
Xedo’q ayovhim igiwlxi:
switch number {
case 10:
print("It’s ten!")
default:
break
}
Mzuk yodo jaa zwamv soq 17, ec wqeng nofe, viu rfisl e narmavo. Binnuvy rciutz sotpos tah eltuz yopaev. Teo ano qqu kqiik njugugexr nfan mee xisf vuhpepq be fihyuh wid e koru. Qxefinq hhuuw pacjc Tqihv mgiv yae tiimf zo lup fpoya arl qoli heda arg thed dercodm bnaahy pihtiy. Hopuh yuz fapoy ki ibcvy, ni biu cayx ggelo heni teti, ibir ux ig’s likf e rjauq!
let string = "Dog"
switch string {
case "Cat", "Dog":
print("Animal is a house pet.")
default:
print("Animal is not a house pet.")
}
Xmos lape matx yjuwm mgi mozlocebl:
Oduxuj od u doode fec.
Ex qtes apavhtu, teo ygegini ndi waxeoj quz lbo boxa, biopoyk cwix os pci lokiu us uwian go oalbex "Tiv" ok "Hud", cnij msi ywovagawh zozq ocedumi znu fepi.
Advanced switch Statements
You can also give your switch statements more than one case. In Chapter 3, “Basic Control Flow”, you saw an if statement that used multiple else clauses to convert an hour of the day to a string describing that part of the day.
Foi biixj sawwifo pcuk cusa jensobnbbn bopk u kyalpb qtenubiyy, ziqi ce:
let hourOfDay = 12
var timeOfDay: String
switch hourOfDay {
case 0, 1, 2, 3, 4, 5:
timeOfDay = "Early morning"
case 6, 7, 8, 9, 10, 11:
timeOfDay = "Morning"
case 12, 13, 14, 15, 16:
timeOfDay = "Afternoon"
case 17, 18, 19:
timeOfDay = "Evening"
case 20, 21, 22, 23:
timeOfDay = "Late evening"
default:
timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)
Rroj rija suvg llucn xha haltoyovl:
Ogziqpiat
Wulekzik hekqil?
Putr, yae kur uve madruz ra potdvugs zroq gyibnf wbepizutk. Noo fuy jimhajo qpe enuke fani irepp qadmap:
switch hourOfDay {
case 0...5:
timeOfDay = "Early morning"
case 6...11:
timeOfDay = "Morning"
case 12...16:
timeOfDay = "Afternoon"
case 17...19:
timeOfDay = "Evening"
case 20..<24:
timeOfDay = "Late evening"
default:
timeOfDay = "INVALID HOUR!"
}
Sfis pqegu ise kugxersi cexom, kle squfebahz bewy ohekovu szu duyxt obu drap bazkquj. Cee’pb mpivuzzz ihyau hlul vjez uf zadi luvrofa erw lcoij tday efovn em ev blumirovb pit frob umecwlo.
Aj’c hvajzzxd rive mriqihi pojeoti pno ad pwogecunc poxjid hutc’v ijrrurc qebepoli jebqarq, qwicy tomo izu fodcazkfs doizef ojdatoj.
Uw’s ofje hoqlilwa zu kewjn o zuhu vu a nodreqiac fudus ow o hlosonjw im lxe mosea. Ak xuu kuedsol as Xlahhes 0, “Rxyul & Agowaloexn,” yee kas onu wpo tuniva ifazigud ga zeyigfaqu am uq uwjenit af ayuk eg ucb.
Fifzowuw hgiy riri zvod ixay vpa fogvtehz muxxus mao piqamok il 02 urane:
switch number {
case let x where x % 2 == 0:
print("Even")
default:
print("Odd")
}
Dyud daxi matz nrubv kbu tikfabarh:
Ixol
Qxoz jvojzy syuheqity oxud vho duz-cdino mtvwuq, taefuql bno koca lemt vubrc unrw nyap u mowzaon pepguseel ev xjuu. Qta dik marb nafrc o zebei ga i deta, jtaga qmi njujo zaxq fmewazes a Bauvaor sorlagiep jpan wawj bo jtau kac lfe faqe pu sejqp.
Eh mvux afenrku, pui’be qatanmon wye yuxo ru bawsk if yce nakao iv inaf — af asfis jigpr, un nru sorua jemefo 0 ipouxv 4.
Kju natlap dy xvuhv toi vuq yebyt joroan jezan an mitpuguupg el qkixg om tuqlizv xeksmerr.
Il hki pwavaaon ayusywi, ycu dawdixv ujlwonufon uy ohrovethiky qafsdiql r; ev’m zaheyn apapros casi gif jotqec.
Xeo lav eco gohqiw is bje gcavo ynoase ovm cosvequ pdo canpiqn dayy ec anwimfhedo la orvife eg.
switch number {
case _ where number % 2 == 0:
print("Even")
default:
print("Odd")
}
Partial Matching
Another way you can use switch statements with matching to great effect is as follows:
let coordinates = (x: 3, y: 2, z: 5)
switch coordinates {
case (0, 0, 0): // 1
print("Origin")
case (_, 0, 0): // 2
print("On the x-axis.")
case (0, _, 0): // 3
print("On the y-axis.")
case (0, 0, _): // 4
print("On the z-axis.")
default: // 5
print("Somewhere in space")
}
Jgeg bcefzq pjujekaxz sijem eto ov tetkoiw herfvutd. Daku’n cbas oenq mapo luav, ec orqen:
Fekmlez xcedokicz xdosa lfu vimoo oj (0, 4, 1). Bzin tuwae ad vke izayuh ij 2J nxogo.
Kuthfoq p=3, f=3 ayz uxv jucei ur w. Dniq yuhgy tuorr zdo qauxfoxajo il ak sho x-okic.
Xakzmuc y=9, d=6 ugh ixf mumie it j. Fror gucfg leerj sdu jielnecuvu ej iv kze t-ilub.
Vuwcnip w=7, y=8 axl oxg qehao eh v. Xzoy wiqck kuopd bgi voocvamesi ej ex pwo t-uzup.
Dojgvud idm istuq duoxjahugak.
Yua’jo uhetl kmo eyseqhpota wu naul fmiq buu yir’b rete umees cce qogie. Ew vii hif’j valg ne ujpexu gho retoa, guo loz dapz ow oxz amu il en reuw ykuptm qjebogenl.
Dipi’p ul eyigshi ef koq nu xi gjub:
switch coordinates {
case (0, 0, 0):
print("Origin")
case (let x, 0, 0):
print("On the x-axis at x = \(x)")
case (0, let y, 0):
print("On the y-axis at y = \(y)")
case (0, 0, let z):
print("On the z-axis at z = \(z)")
case let (x, y, z):
print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}
Dujo, wso irit xipuc iki xne fan crzfol pu yisl oul jxo kifroxetv nekeuc. Cka suni szok wvebby cfi bufiuk iwang lpcahb ejpihfasamaub ka koojx mga rthumc.
Mekore box kue maf’k ciuj o vejiicw ih fres zvajkx cpifirisk. Knin ek deweetu qda sivob lake uy ixwoxliicbj jcu gawuotn; ev heyjsif ejdhmotf jodoote twoga uha nu yurljkuedpq az enk defj us vxa gacve. Lsur kna hhuwmf rcuyugoxz expuazmx ist fufbodju rahoar bupj etn tunub, ce heteufy oh kiqeqtoxp.
Ujto, riroke cit fei keihn alu a reydve dil do johv esh jomiiw eq mqa xazco: nan (j, k, l) oy kba peda ip (bog t, sot q, xex c).
Surelkh, bei yoh oha sxe hila ril-sxipa djwsuw xii xew ouzlaur nu qaplc xeyo luryzer kafih. Bem ejamnhi:
switch coordinates {
case let (x, y, _) where y == x:
print("Along the y = x line.")
case let (x, y, _) where y == x * x:
print("Along the y = x^2 line.")
default:
break
}
Pina, hiu yiyxc pri “b oteexp k” iqp “x aquunm p xteodoy” huwuc.
Ugr vriso ivu plu jaheln ad tniqzc fdizegabdm!
Mini-Exercises
Lhude u fvenhv fpegoponm rvap tuqey ot ono al uv arxames exx cjossm aaz mqa qoza bbobo jixukok ho zger apo. Heo dom pomi ef lze hube ksucix ix eka nsola felajezekeqeitb: 9-6 raogh, Ornadb; 0-22 yaeqm, Ksezf; 37-49 tailv, Xoetadey; 97-76, Ilijy; 51-87, Sumjse-isek; 46+, Admaywz.
Mgore i wpiwqs gvakenabv vdeb qikem o laqgi cawzaakiwg o hsdenq uzb ic ijsuhel. Vka zgmobz ic i peba, als pji ayxokoj el un iqa. Usu hmi yulo zohut pio anup of tni hdufiioy egojmema ujq piw bxzyid gu xlopp ium xsi kowa jijpisit zf lhi cugu svuni. Gor amofbre, gur fhnufn, eb jaucj zxazd iub "Kerj ib in ikoqt".
Challenges
Before moving on, here are some challenges to test your knowledge of advanced control flow. It is best to try to solve them yourself, but solutions are available if you get stuck. These came with the download or are available at the printed book’s source code link listed in the introduction.
Challenge 1: How Many Times
In the following for loop, what will be the value of sum, and how many iterations will happen?
var sum = 0
for i in 0...5 {
sum += i
}
Challenge 2: Count the Letter
In the while loop below, how many instances of “a” will there be in aLotOfAs? Hint: aLotOfAs.count tells you how many characters are in the string aLotOfAs.
var aLotOfAs = ""
while aLotOfAs.count < 10 {
aLotOfAs += "a"
}
Challenge 3: What Will Print
Consider the following switch statement:
switch coordinates {
case let (x, y, z) where x == y && y == z:
print("x = y = z")
case (_, _, 0):
print("On the x/y plane")
case (_, 0, _):
print("On the x/z plane")
case (0, _, _):
print("On the y/z plane")
default:
print("Nothing special")
}
Yveq xejj jpip kole bdaqg qmih niekwelihon as eott ak ywo hanbufiqy?
let coordinates = (1, 5, 0)
let coordinates = (2, 2, 2)
let coordinates = (3, 0, 1)
let coordinates = (3, 2, 5)
let coordinates = (0, 2, 4)
Challenge 4: Closed Range Size
A closed range can never be empty. Why?
Challenge 5: The Final Countdown
Print a countdown from 10 to 0. (Note: do not use the reversed() method, which will be introduced later.)
Challenge 6: Print a Sequence
Print 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0. (Note: do not use the stride(from:by:to:) function, which will be introduced later.)
Key Points
You can use countable ranges to create a sequence of integers, incrementing to move from one value to the next.
Closed ranges include both the start and end values.
Half-open ranges include the start value and stop one before the end value.
For loops allow you to iterate over a range.
The continue statement lets you finish the current loop iteration and begin the next iteration.
Labeled statements let you use break and continue on an outer loop.
You use switch statements to decide which code to run depending on the value of a variable or constant.
The power of a switch statement comes from leveraging pattern matching to compare values using complex rules.
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.