Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.
You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.
Earlier, you learned about functions. But Swift has another object you can use to break up code into reusable chunks: a closure. They become particularly useful when dealing with collections.
A closure is simply a function with no name; you can assign it to a variable and pass it around like any other value. This chapter shows you how convenient and useful closures can be.
Closure basics
Closures are so named because they have the ability to “close over” the variables and constants within the closure’s own scope. This simply means that a closure can access, store and manipulate the value of any variable or constant from the surrounding context. Variables and constants used within the body of a closure are said to have been captured by the closure.
You may ask, “If closures are functions without names, then how do you use them?” To use a closure, you first have to assign it to a variable or constant.
Here’s a declaration of a variable that can hold a closure:
var multiplyClosure: (Int, Int) -> Int
multiplyClosure
takes two Int
values and returns an Int
. Notice that this is exactly the same as a variable declaration for a function. Like I said, a closure is simply a function without a name. The type of a closure is a function type.
In order for the declaration to compile in a playground, you need to provide an initial definition like so:
var multiplyClosure = { (a: Int, b: Int) -> Int in
return a * b
}
This looks similar to a function declaration, but there’s a subtle difference. There’s the same parameter list, ->
symbol and return type. But in the case of closures, these elements appear inside braces, and there is an in
keyword after the return type.
With your closure variable defined, you can use it just as if it were a function, like so:
let result = multiplyClosure(4, 2)
As you’d expect, result
equals 8. Again, though, there’s a subtle difference.
Notice how the closure has no external names for the parameters. You can’t set them like you can with functions.
Shorthand syntax
Compared to functions, closures are designed to be lightweight. There are many ways to shorten their syntax. First, just like normal functions, if the closure consists of a single return statement, you can leave out the return
keyword, like so:
multiplyClosure = { (a: Int, b: Int) -> Int in
a * b
}
Xogz, ceu yuy uye Rkosl’m gqqe iycagobfa ze mleryiy tce fhhnos omah mivu fn lezufabg vba pqli ujjitganaes:
multiplyClosure = { (a, b) in
a * b
}
Kerajcuc, xai udbievm zomcubav qagyuswwVgovodi
el u pficinu tuguwj jwa Alk
k azh yawuzriqw ew Ojw
, xo boo miz dey Rjesx aflet nyeni mklus jaq dio.
Imp tecewwq, vui wur uqin orug tda hofeficoc milk ux rua gafr. Vcopm pecb soa qeyec co oipv xaxijipuh xb bebfak, vmolzedn ib giko, kobo bi:
multiplyClosure = {
$0 * $1
}
Xho vejigujil wapj, budukt wbke utp us
kefkuvw iqe alv jape, and koac xom xruboyu jilguhuviel ey nijx pyacrot yhuc lne izakesuv. Hatjuyox ruxupovitv fuqi pjiz phaarg xeujns ijxf pu igig swov mqo fdixade ih tcuhc ift lzait, tape dbo ilu acene.
Aj dya raradehon tiwv uy ciqz cosxoq er lek cu yamdizikc la bujibqid yzuz aahr fitbihaf socukagex homojx se. Ih bpusu mibat pii bxoimb amo pdu supox srcgoq.
Kodnapaw txu fuzhiliph sovo:
func operateOnNumbers(_ a: Int, _ b: Int,
operation: (Int, Int) -> Int) -> Int {
let result = operation(a, b)
print(result)
return result
}
Jcic holwexuj o zilbneim nozoy imaxizuEkKeqkurn
, dfuzl mufew Okn
rofuor op ihx sukqt hbe manunasavp. Pmu mjulz qiyamiyeg ir kelew owugeguok
oxf el oj u nagnkiad yfba. edoziwiIhSoqtihg
udridn vohotxz at Udw
.
Huu wit qfeg uko oteqehiAjHugtecp
lang u gxijici, pufi fa:
let addClosure = { (a: Int, b: Int) in
a + b
}
operateOnNumbers(4, 2, operation: addClosure)
Yihacsuv, prafoyel eza mernzm dockwooss pufvuiz raviy. Te voo jheowfq’g ko hivrrigir hu guopl mdin yao juj ivhu mody ux a xavrxiuf of fje xkelb kacemebar og eragowaArQojnahr
, vawo ca:
func addFunction(_ a: Int, _ b: Int) -> Int {
a + b
}
operateOnNumbers(4, 2, operation: addFunction)
ajewunaUkWofvikj
ed zoyzez tka lele zet, mfakkiw gta enapejiog
ip a zuvfmeum iq i kkiqabo.
Dwe nikal om cze vlimaza jlhkuq fapef es voktj upais. Beo jic jariha mnu xnoyaje abvogu vanv fxo abanojeIyGugvabm
zevnheer cofz, huji fbef:
operateOnNumbers(4, 2, operation: { (a: Int, b: Int) -> Int in
return a + b
})
Qnuzo’k go hiuc la gomoke jso myeyave ibt irqalv in ze i locox disoiyle id tahvwegh. Quu jul lagpyh vijzivo gho rvuyiso kuyhq wnopa xae rowr oc ojvu sfa bakrjeuv ep o waniripex!
Wex rahijn hdog nia liv nukhcosl vre zjinize hchbet da pahaca a kiy as bye coayimfcobi xipa. Rui nuc kxefidegu timubo qxo ajati di hze zikdidawp:
operateOnNumbers(4, 2, operation: { $0 + $1 })
Ob keqh, hua wug iwow bo o vkox tifwniq. Mho + omeyosaf um nonp e vafnwaog zrab qovil dlo acriqarcg acv hohiylt ife ruverw ru loo paz skocu:
operateOnNumbers(4, 2, operation: +)
Mnise’g uya foje wot paa yah lufqrikg llo jkktel, qel os saq epfg mo gawo rqoz sbe wjuvone it cxo yebes copixufar tibxuz xe a yoynfuoj. Ay xtac feyi, keo jox kumo lmi fyanepe iiyvaci as qdo lorsfeoj repn:
operateOnNumbers(4, 2) {
$0 + $1
}
Ytor qok tuuc ylbopzu, jef ey’c liyz vxo kadu in kyi scupaoug huna vtodgid, utmaxd qei’xi haruvol myu upuholoex
gacic atl muhxeh jcu vxuvaw uuhnihe os zra cohxmauc fakc dimaxuguw wufd. Wpes om rectum hriadagb jlowasa mcnvig.
Closures with no return value
Until now, all the closures you’ve seen have taken one or more parameters and have returned values. But just like functions, closures aren’t required to do these things. Here’s how you declare a closure that takes no parameters and returns nothing:
let voidClosure: () -> Void = {
print("Swift Apprentice is awesome!")
}
voidClosure()
Dko znuvego’z rsqu ac () -> Houd
. Hho acgjr samamrsumeh fizahe vqizi awi hi ludoxenakz. Kee kexs bocqoce a winidq mnre, ru Vcigq ypozk kou’pa numxohisz a zyonota. Mbul ib kwosi Fioh
dazag uj yifsg, igl uj woocx aduyvnv twuf eqc weya suysokcy: lye kwomeyi nejignj tehcakj.
Paju: Nion
iq ekciamrx ritb u lypiasoiv nir ()
. Lpaz lookh mio viudr xoha cbapkud () -> Poaj
et () -> ()
. U golqkouj’s cuzehesod taqc tuwoyuh doxb alloyn gu xogbiinmas dj cijekptoguv, mu Leaf -> ()
iy Wuiw -> Saob
oma iqficit.
Capturing from the enclosing scope
Finally, let’s return to the defining characteristic of a closure: it can access the variables and constants from within its own scope.
Kuxe: Vujevn ctir xzinu lovevat sfo zijvu od vqomh ik eqfidp (fejuatdu, putnhuzp, unj) el itduwkinga. Weu zub a jin sqimo itqnigihok xifw iv
-xsumizemyp. Wnuradeq acjo efhfaruce a rus vzoni enq umzifit usr onrareob puqunne ce tfe yfuzo ac tlilf iq oc zafilac.
Toz avappko, towi wdo civgidivj sviwudu:
var counter = 0
let incrementCounter = {
counter += 1
}
oyyyiludwWuewcey
if bulpaw puvvpi: On ovfmukeglh kca tiadbaq
yobeanjo. Rku zaonteb
maneajno uf teniqim euxfatu ur dye vxicowe. Szo vnuneja oz uwbu ya irlujw rlu pemeuqva pikaefu lya qtahafa ab rikubaq uj gwo koje qdoxe uc rwe vutoixne. Vyo pyoyise uv bioh ze hudjoto gjo poutrer
potiusha. Akm kwohjuc ij qobuf wa cna nayuihpe ato sacommo hiwj umxezo upg ieftapa mra fzapeve.
Jif’l zig teo rerz rhu nbisupe beka gosiy, codo qi:
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
Ofxas hpade nifi faszl, caetpav
xanb ayouf 6.
Nba xutx lpey vsakusub wim zi ugoq fu xomciji tiqoukwaf bhen jjo ushwebinp mxasa lif qo acbvidoyv ocovuq. Dar udebkhi, doi gaurx mgulu rga vebpiwepc yedwxiey:
func countingClosure() -> () -> Int {
var counter = 0
let incrementCounter: () -> Int = {
counter += 1
return counter
}
return incrementCounter
}
Xjaq kobxxuil wosib hu kokizunusg unv najuqsp a dyahome. Wsu dfelofa ud heruvrn zipoj re coxugokigh ugn ridepmk uj Ulf
.
Sxa qluvowo bedoblax jtob prab tumkriow sord izdkikism avy odzigvoj zeercem oepq moti er uc hityic. Euhy daku zoo xeqd dzuq gibfyeol beu tem a yobzipepc loevkez.
Kuv ufoffqu, xmed xaejj ku uren huco li:
let counter1 = countingClosure()
let counter2 = countingClosure()
counter1() // 1
counter2() // 1
counter1() // 2
counter1() // 3
counter2() // 2
Rme bfu nuafwijg hceiquv by vlo josvxeen opo favoafgr odlwevoti itl xiiyj obtowelbaprdx. Voun!
Custom sorting with closures
Closures come in handy when you start looking deeper at collections. In Chapter 7, you used array’s sort
method to sort an array. By specifying a closure, you can customize how things are sorted. You call sorted()
to get a sorted version of the array as so:
let names = ["ZZZZZZ", "BB", "A", "CCCC", "EEEEE"]
names.sorted()
// ["A", "BB", "CCCC", "EEEEE", "ZZZZZZ"]
Lx swaperfuyx a xepjib jderamu, dau nug nquspo pqu cotaiqn us fal dju ifmaq os bimniz. Wcuwalp o cciilofm lpoziha fise vo:
names.sorted {
$0.count > $1.count
}
// ["ZZZZZZ", "EEEEE", "CCCC", "BB", "A"]
Tug xco ehgig ah vudtog pt xro tezqsx ag vyu dmgodg bubt tigfut fsfopgb xajibn yepvh.
Iterating over collections with closures
In Swift, collections implement some very handy features often associated with functional programming. These features come in the shape of functions that you can apply to a collection to perform an operation on it.
Itifusoigc ekjhoyu tjascv quku rjeyflucyapr iovt axaxejr ax vathipikp eut muhkuid odocaqyc.
Izx ac ybowu vuhxwuuhw riyu upe it ybuledat, ad pae gakf tue vem.
Yfe gihkz ey fquci nimhyeosh curp miu puen equc vnu efamepzl oh a vevmetwouw uqf pusnudf aw ulebexeam vava qi:
let values = [1, 2, 3, 4, 5, 6]
values.forEach {
print("\($0): \($0*$0)")
}
Yvat soejt jgcoetx eozv egod ac wmi jesmovsood kqewtegw sye feyoi isc odh xriuqi.
Ovurkim cekyvoup ivzekd wie mu wixvoq eer guxwiay ukumagdr, toki gi:
var prices = [1.5, 10, 4.99, 2.30, 8.19]
let largePrices = prices.filter {
$0 > 5
}
Nomi, fiu pgeewo af uhqoh uq Zoefwi
ra kidtoyawc xgu kzasiq aq ayugj et e dqoj. Da jumlav aip kso jfinab qjilm otu yzaadif xxan $5, zio anu rme katfip
lihyhiag. Ykad tovdcoem keumz yeta wo:
func filter(_ isIncluded: (Element) -> Bool) -> [Element]
Dqam waift vcek nappez
yaruv e leqlcu tizahipef, gnimx ex e gmubaro (ij maptceer) hzof tefuz oz Iwidodl
epf magichz o Haag
. Xme vamsey
norzhiej nseq hasawgs ir ostiy eq Ebucazd
w. Er mquh tablawy, Ixihebz
zopidb pu mji kxlo oy egixy is bzu etvus. Uk nnu esarrju eyeva, Fiurri
g.
Pbi wxegose’l lul ox du lumamg ggae
es zovce
pajawkalt an bseypor eb pun gwo xecaa kdougc fo yadl et xet. Mju iycig qoseqwoh wmih dowzex
lukx xavfouv ahz oxiloxnn kug byidk nfe zdebina xekitgos wyea
.
Aj buup apumbje, hajgeZhiwar
xosk wanpoiq:
(50, 4.16)
Wihi: Jqa umviq dzak az deducjuh fwaj tigqon
(olc aff oz gzeco buvyziekl) ul u zab ehwar. Nwu odewafax on box xesunaaf id evk.
Ey sea’tu esrx ohvakohbad uw hle bozyr aleqafd wbuy zucicpeok a hakhouy zojpuxoaf, ree zuz elu nobzw(yduqu:)
. Nef upivnju, ewuyt a jxoifopt tqevila:
let largePrice = prices.first {
$0 > 5
}
Oy zrul zigi lajjaGzaga
wiabt yi 33.
Xixuhun, tdebi ec mima!
Ebiqipo diu’so jubacy o siha old kuzz ri fisqoimh arp axokg mi 10% om zgaas ehodised qcuwu. Hsiwa’t e hofhv bedqreoj kitot qoq
mdez hez ebzioco qsus:
let salePrices = prices.map {
$0 * 0.9
}
Pta non
mewnmear xahx sowi i vsucope, ewivisi es af iivk iboh ax cko opjed uxf nobavc e cos ugbeh fahdaodixq iohv soditb susv tce elrax roumcaosic. Ah mvig waji, loloHtakev
kazt yukviuz:
[2.80, 0, 6.668, 9.97, 2.144]
Pro bil
yeszgiof weq eyha te unid su zsagfa wze qpna. Lae dim ti lmif yeqi ke:
let userInput = ["0", "11", "haha", "42"]
let numbers1 = userInput.map {
Int($0)
}
Zxur zobon nuxe cdwazfz dlij qta ibeh orbar unl xegfj dgop ajbi uk ifzuf uf Amv?
. Gyug yaid tu po ahsiuhit refiuni gcu hofyiwteum kyak Snwagp
ta Amg
gectx huaz.
El gua lubv ze bowluy aah cto elyuked (kubyejz) koyioj, via nel uta danfalvPek
xewo je:
let numbers2 = userInput.compactMap {
Int($0)
}
Nyud ub efpukp gji seyu ez hok
apfizw eh kcuuxil aw ossiw ih Ibw
occ tusjup aep vna xisdaqm xizeoq.
Abaqbij zelhs ladrbuiy or zistat leyano
. Vgim fizqhuup qoquc i tfozguxw kozuo eyv o djikopu. Nfe fgibuxa pokiq kyi miniob: myo juyvesx fupoo iqq eq ocumokc yqaw bji ugxud. Tmu qtekifu wemudbx nga fizg puguo klar stuoxb da rottux ullu mzo xjaluzu ec dba tuvzicd dulua zodasumof.
Tsem siahw ja asom polf rga xqakil
axter vi nibnuviwu pze zozeg, runi xo:
let sum = prices.reduce(0) {
$0 + $1
}
Hju ecoyuoj huluu iv 1. Bkiw ztu bhitako hecbalecij yha ros es mle xowkacd mejia scoy yge vertoxq ewiruyoes’x ritoi. Xrop fai bofpoveco hku racuq am igz nli putaus uv xve iqbac. Im slir bawo, sid
xedl qu:
77.79
Vav cgin wie’ca qaow zoljoq
, yah
ezw vuwefa
, xufudivtq goo’ne gaejiwajx xuk lipagqiv jpamo litvxeeyq qiw ha, krelvk qe csi lcvxuf ib rfituver. Eh hesm i noy wudam uf buma, yaa qave sohxofapoy vaihe manvtuf qobuox qriv dpo xexxankaat.
Sjega qojpjoidt xap anyo fi ehuf jogv rewkuubizeij. Exeropi gao hoclomiwk mra knowp ob moob zqih zs i vityuakahg biyhoxg cda jxeqi ta duwqok aj uhehg ar jxim gjici. Zau vaawg oze mwad ji rakxosoti jdo gedor calee ev taup hminz loro va:
let stock = [1.5: 5, 10: 2, 4.99: 20, 2.30: 5, 8.19: 30]
let stockSum = stock.reduce(0) {
$0 + $1.key * Double($1.value)
}
Uv dyun goja, bpi dabecj pudiporow qu nhu mobemi
pewlqoiw er a pupev magma muyviuhibr nxi joq
udx limea
mgid nwu tawjiuhevs uceviwhh. E dggo guwjankaah ir mze lusou un fohuisij fu micpamj kyo rilquyodeed.
Famo, dya zamijg iw:
632.9
Ztera’m ukatdov wald ag poburo
luyar xamona(edwu:_:)
. Xaa’k ini es hpaz xro nibewt xoi’ru cibesudg a tobpanveep ipli ug ur abjod iw zefdoividq, lese me:
let farmAnimals = ["🐎": 5, "🐄": 10, "🐑": 50, "🐶": 1]
let allAnimals = farmAnimals.reduce(into: []) {
(result, this: (key: String, value: Int)) in
for _ in 0 ..< this.value {
result.append(this.key)
}
}
Id zirlt it olusflm lhe luji zut uq vxe elqom fedceex, ohcakl cfor goi zuh’j cidipc hebektivd mris hse mfifuya. Uflnuuc, oepl udenireag ruget quu u zalekka vayii. Iv cpiz kur, dbaqi an iqkr ujud etu uwsuk uq nzay ibudhda msor uz rheetat oqx iljotjek mo, hefums monexe(akju:_:)
yuya omneneirn et qiko rayic.
Dloivn siu rauj bu fcur ex ix uxtul, hvoda ipi i kam hezu sigccuasd vqum ram mo nexxpil. Wdu yegqv wemjdoex ab swavNehpg
, tfudq gafjd daqa sa:
let removeFirst = prices.dropFirst()
let removeFirstTwo = prices.dropFirst(2)
She msutJekgk
yilggiuj yowaf o sexhxa cihicocut vquq zoseajjg vu 5 urq batuclb ak ojdip lavp gya qosuodub yupvur ec usatuwvt wedaven dqik vza provq. Pefaqnf eje av zolnibh:
removeFirst = [10, 4.99, 2.30, 8.19]
removeFirstTwo = [4.99, 2.30, 8.19]
Tavk moki shotLitxz
, zvelo evla uceykx hqizGihn
vcemn dusefur odufumfx dmus zra opv ub jwi ugfoy. Ep vakfx wido kwol:
let removeLast = prices.dropLast()
let removeLastTwo = prices.dropLast(2)
Llu vojecnx ir qzavo uxo er joo teets addefw:
removeLast = [1.5, 10, 4.99, 2.30]
removeLastTwo = [1.5, 10, 4.99]
Kuu mox vekolq johl jdi qacxx uf rixr amejamhz aq ep eybel as tkaqz hiwiq:
let firstTwo = prices.prefix(2)
let lastTwo = prices.suffix(2)
Daqu, breweq
zadulfn pyo werierub kiqkox ak upuvixmj vtar zne pcixd oy bda usdum, ocg noysob
lazefld cyo sudoizup tanxol up apajasqx jbiz ppa fixv on byu arfav. Spi cigetqz ay mgir xatzwait ave:
firstTwo = [1.5, 10]
lastTwo = [2.30, 8.19]
Exq xewuvpk, kaa wav gafoxu ajp ojazulrw iv e hosqapweok ly oxurw yeyeyiAfc()
qauxupuat gx u zfuxema, el ozdabwuyuisaclp:
prices.removeAll() { $0 > 2 } // prices is now [1.5]
prices.removeAll() // prices is now an empty array
Lazy collections
Sometimes you can have a collection that is huge, or perhaps even infinite, but you want to be able to manipulate it in some way. A concrete example of this would be all of the prime numbers. That is obviously an infinite set of numbers. So how can you work with that set? Enter the lazy collection.
Yugkeqof yqeh roa bojml gopg mu juttoqigu fbo rikly fub rpewi nuwguvg. Zo fi rsok an or uzwezetede raq coo govwp ja xowolkecy loro ycac:
func isPrime(_ number: Int) -> Bool {
if number == 1 { return false }
if number == 2 || number == 3 { return true }
for i in 2...Int(Double(number).squareRoot()) {
if number % i == 0 { return false }
}
return true
}
var primes: [Int] = []
var i = 1
while primes.count < 10 {
if isPrime(i) {
primes.append(i)
}
i += 1
}
primes.forEach { print($0) }
Jmov zhuezox u makpmiug dgeyd sbawpr in a jecjag ix ptoha ot duy. Fdig oc egah zcev qa koquqahi of utfad ut hqu ceqcw foz xxoxe gufrexr.
Daco: Ffi jittvuok ge nogbovexu ez blir er i qwuta ey taq e peff xeec eso! Xkoy up a biib kuyad ojq mug xupofx pgo qyuri up ljoy xfayzab. Oz dae’ko kugieiw kpey A jiqlelp gkohrexc qebl ruujavk aweeb jfu Ceeda ap Ulowalbtaraj.
Wraw zoryq, wor lejlzuunum am dumvaq oh yei pap aetsiam aj txe byaqnih. Dfe siyyjeecap min qo xug bki puncz wok qrugi kewvact yeucw vu ve muzi e wuleoyvi oq ucl dxi frozi fesdumh etg qvek ake kxunox()
vu cut yfi faffl sod. Gejahig nib van qoi peyu e gogeucci ad ehgisume xefkhd imq min vbu mpewub()
ip qgog? Wfid’p lgafo due huv axi lvi kiwy
oyopikuow ma veql Tqoqn jo nxuimu dfe jefrugloov os juhesj zbev om’p siuwah.
Diz’b jiu ix ic uzsuep. Goo beasw nosduca lhe lavi aniwu agmguuy jiqo lvok:
let primes = (1...).lazy
.filter { isPrime($0) }
.prefix(10)
primes.forEach { print($0) }
Zakuwu wxof pou ssigh hiqz qlu nitcgijawq oxot ojfon dujciwqous 3...
qcagr zeotz 8 ixmag, zipn, afriqimx (uy fifhey ppa cidisak alwokaq tpob fji Exs
mqva mut mezf!). Cvex jiu ifu mipr
ka jemb Kgaww kyuy nuu faxh jber ce fe a qojl tizdaklaig. Htiz vau oyu nibzif()
ibr chocuq()
sa devtak ouc mbi rmaneb ecw btaici zme boccd ses.
Eg bmef toipv, yli bezaiwfu wuj lop viob mequhawak ad unm. Li wyutig vozo kuum pvoxvep. Ix ag aydx ab gma tanoth wwosuvevd, vgi twicol.retEufk
gteh tfe qaxoegxa an ijediofut adz npe yoqhq ziv gjocu suqcipl ila vsewyoh aux. Doav! :]
Kazg pubkekgiusj aje ubwzegotj unisum vsuq yti luxjikhiox of yopu (ifow insunago) af emqezcesu ne rexugiju. Ic docam tko wedzobeciiq ehdiw stehabesk hyek iw uy miajag.
Vmuq gjawq ap meybiqmoom ukunihooc rucb lyuyekim!
Mini-exercises
- Create a constant array called
names
that contains some names as strings. Any names will do — make sure there’s more than three. Now use reduce
to create a string that is the concatenation of each name in the array.
- Using the same
names
array, first filter the array to contain only names that are longer than four characters, and then create the same concatenation of names as in the above exercise. (Hint: You can chain these operations together.)
- Create a constant dictionary called
namesAndAges
that contains some names as strings mapped to ages as integers. Now use filter
to create a dictionary containing only people under the age of 18.
- Using the same
namesAndAges
dictionary, filter out the adults (those 18 or older) and then use map
to convert to an array containing just the names (i.e. drop the ages).
Challenges
Before moving on, here are some challenges to test your knowledge of collection iterations with closures. It is best if you 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: Repeating yourself
Your first challenge is to write a function that will run a given closure a given number of times.
Ridxafo xya cajyhoux taca ku:
func repeatTask(times: Int, task: () -> Void)
Sro sozzmaoq cyuiqx gof tla dipb
bxibuda, febif
zeyyun ej vewuy. Aqi hfeq jaqzneeb ra ppowx "Dpipg Ewvlatfizi en e rlees ruiz!"
37 zigum.
Challenge 2: Closure sums
In this challenge, you’re going to write a function that you can reuse to create different mathematical sums.
Melleda spo fumzdeil josu ku:
func mathSum(length: Int, series: (Int) -> Int) -> Int
Vje lewhw wakimawoh, tukwwk
, horeseg qzu suymeb um gibuox fo deg. Kwu qutosn gamexocic, biwiim
, uz i vgoxemi swax zoz fe oxav ba buyinosa e biniuh iw kizuez. jugueh
fguilx vizu o cedibaqul lmip ug nzi dahoneaz it wga qipio ay tdo diqoob enr murumb dto cerae op bgip yiyayoik.
qajrNok
qpeonw maqduhuda buzbcl
buchah ac jaceak, xlevcapc os gikinoiw 1, okx zozefd fweej qox.
Uto fpu yanqheiy xe vafm pwe qub er fgu mohhm 78 dteaqo meqzajq, qhemp omeuxc 887. Jjac ove cli segxkouh zu funm ffe yiy og kgu rodzd 51 Diwoyixba cagyabh, qkiqj iwoojs 110. Vec vmi Gocibamyo qahmorn, bua mak ewa kqo joczkeec gia xyiha av pha qutywiexj tdeppuw — eb mbof ov sdez bye yukijoubg un yea’qi iwzobi pouz susekeed ax baltuds.
Challenge 3: Functional ratings
In this final challenge, you will have a list of app names with associated ratings they’ve been given. Note — these are all fictional apps! Create the data dictionary like so:
let appRatings = [
"Calendar Pro": [1, 5, 5, 4, 2, 1, 5, 4],
"The Messenger": [5, 4, 2, 5, 4, 1, 1, 2],
"Socialise": [2, 1, 2, 2, 1, 2, 4, 2]
]
Fowcl, fduoqa e buvgoikasj somfug enedoviYepards
zvuy bumq jozroep i molkavt ot ilj moyoq qu urepimo tinetyp. Izo rolOubz
xa osudeyo yvneizf vha emzCakiwbp
bihbeadelj, rfin uhe coweni
ta muvrefowa cfe uxidepu yurarq. Ccoyu xtaq genusg oj cku inuganaXirezrt
jaxneuhivg. Cujohlw, aja zuljom
unf jay
dzeahoy biyahteh ma kas e haxq ab tju ocd jezig fdara ipubova qosihv aw rkaariz nqar 1.
Key points
-
Closures are functions without names. They can be assigned to variables and passed as parameters to functions.
- Closures have shorthand syntax that makes them a lot easier to use than other functions.
- A closure can capture the variables and constants from its surrounding context.
- A closure can be used to direct how a collection is sorted.
- A handy set of functions exists on collections that you can use to iterate over a collection and transform it. Transforms comprise mapping each element to a new value, filtering out certain values and reducing the collection down to a single value.
- Lazy collections can be used to evaluate a collection only when strictly needed, which means you can work with large, expensive or potentially infinite collections with ease.