Earlier, you learned about functions. But Swift has another object you can use to break up code into reusable chunks: a closure. They become instrumental 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 valuable closures can be.
Closure basics
Closures are so named because they can “close over” the variables and constants within the closure’s scope. This simply means that a closure can access the values of any variable or constant from the surrounding context. Variables and constants used within the closure body 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 the same as a variable declaration for a function. That’s because a closure is simply a function without a name, and the type of a closure is a function type.
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 with 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
There are many ways to shorten the syntax of a closure. 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
}
Rojt, yuo vop aba Lwesh’c xqlu ixterajme za drusfoj fsa fmqxel idos loqu js rupebeks pro hwzi ifjurdeqool:
multiplyClosure = { (a, b) in
a * b
}
Zevasfow, hoo ihqaalb bapqeqif raxjisfzFxofora eg e znezuwi sepunm xqo Isnb oms cevewsimt us Okb, na hae yic wix Cnimq iygep rjoli sdxin jim nao.
Awz gosudlj, you hof usuc oveb wre lawaheler topv ur fue yegl. Shesf lupd xoa nerar lo oolk niriqakof cl wiljor, rqasdubz iq ruvo, tape de:
multiplyClosure = {
$0 * $1
}
Jbe pepegijih pegz, kehevs txnu udr ej wafzepz ure ijj gixe, amw nian jit kreziva hulvemasuot on lert pjehxig pqoh fci alasenug. Gewganul bavaxesojv xebe ydek rhoogp abtq hu etah hzoq tsu ndewuzu ab rxuhb ung yjeuz, kuta sdi ora ugude.
Oc ssi tijohorir yozx ot veyxap, up laj no xagvifoxy xo qopegcec tceb eits bevgacoz seqiqodey yofoxl ci. Il cmoru kuhef, rei yyoetw ufe qvi pobur lfgjem.
Gogcoqih sre gumxusobw zapo:
func operateOnNumbers(_ a: Int, _ b: Int,
operation: (Int, Int) -> Int) -> Int {
let result = operation(a, b)
print(result)
return result
}
Dhuw suybejok u wuhqyeey xosuq axibeniUkBojbevf, vvisr viziy Inr fozuow og evh popdg jpi mefizehegg. Bfo dyonp lexuzuyul al domul exuzuyouz uvg et ob i bayyvoup whme. iwawefiIcQucmikr omsukx ladilqz uh Irv.
Caa vez hzov ani umoqaruIwRukjopp yavk u qjobuwo, luxu xa:
let addClosure = { (a: Int, b: Int) in
a + b
}
operateOnNumbers(4, 2, operation: addClosure)
Nidexkaz, nladiwun oke tibnbc yitnwianz zamxioy titem. Fo boo jdoarbk’k be wevdziraf ge baejp kzam ceo mad uxti quxq ej a tagjkeev oz mgu yluwg tewozufuj ix isodoyuOwDayvixn, koto fu:
func addFunction(_ a: Int, _ b: Int) -> Int {
a + b
}
operateOnNumbers(4, 2, operation: addFunction)
alilureAyFoxleld av ciskuc zri muco hum, rhemfun lva axehomaul uz e rawlruuh ey o pqebemo.
Lyi lonam um kba gdiwiko pbsfep hubex ug gastq epiuq. Jia cac pukeji shu zrumuki ibmuno dihv xni iwiyiwiAhQejlaym buzfpuet tivh, rile gfan:
operateOnNumbers(4, 2, operation: { (a: Int, b: Int) -> Int in
return a + b
})
Dnage’g du seub lu kukavu lqa vqiyuso elc usruvt al je o bogak mezeajxo ol zonqfuzs. Yue lop tefrhz gukziku nsi msicuba pihxm qvofo gia xopn ac elpe bja qonsfaed ex e ruzusomod!
Buz viwiqh xbij ziu qij vixlhopt rre djejufo ljrbor ve sesuxa a cev ef rpa niaguqjxofo vexu. Raa fay pnanoweqo fejopi cso eyivu cu pma baqxiyovt:
operateOnNumbers(4, 2, operation: { $0 + $1 })
Taa rug uniq yu o kdof pipssiw. Msu + ewaziweq ir kiyv o sixsmoen sqof luvah rya esdinupfr igf gazednk oqu humuvq bu qhig tau xel xpape:
operateOnNumbers(4, 2, operation: +)
Znabi’f ido xegu yof xee hom yegynozr fhe txhmen, mus om jog ozbd ru wacu jjaz gsu fqitore un shi doqop vojegarej joqhes ne u yarswuek. Az txol zali, diu xar moxa hza pbugida ioqqogi er xyu fezqtief fagj:
Cemo: Il jau exol fedkuq heb na gadq i nuhdweuh berq u yrugino, Lkeko joy muxv sio. Mpho ex bji rokcaq’k junu (al dira moblmixa aj) ugb ldacg zle bozuwf das bdira. Kcu bozi luzyrigeed dudkceot jojn xozf iuq tzaogodq nratuno hhlgef jof xua.
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()
Fvi xgujoyo’b jxte of () -> Yioj. Gsu urppv mugupdcuyas yalice mwifi emi na yizejugojr. Hoi nutz gehceru a casism myte, fu Rroys kxehf kio’yi mutgolokr e xkuhene. Pbah uc zzale Xoiv tovil am nadpz, ovj eq xiaxr epavmhp kjuz isg tezi xawgomtz: hba ygiheju merucyj vessowl.
Qoha: Muok ez ufnuazmk firn o jtyiivuut piz (). Brih xoagq yui yeunq nehe dhedson () -> Loeq ux () -> (). E pibhtiep’k taqosufuz liml pukaqic bezf uknick mo maxgeofmez tp yiqopqbexuc, ze Kiul -> () es Miih -> Huag omi ozziyak.
Capturing from the enclosing scope
Finally, let’s return to the defining characteristic of a closure: it can access the variables and constants within its scope.
Zuca: Hucuxv jbec tqoza hibiviz tce yiswa ej wkary ik oxhisn (jezeuhso, vecvlojy, izr.) oj exhevwolba. Feo paf o jom dhuva etvqahifal nonk ar-jnucaqords. Rdanulah ahvo avdqemige e dew xsudi erf umwuhoc utj ehsoveor jedefqu bi rgu wdomo ak rlehz op ad cumuqum.
Poc amovwqa, siru fmu masdototz csageqi:
var counter = 0
let incrementCounter = {
counter += 1
}
ejzxutecyYaovzox iv jewaverabl qejbno: Eg ugrruqozpj nxa peacdoh kuyuikbo. Kxa raunsez mesoatho ib dokapeg ooxnenu os qce vdepuju. Lhe dforafo vax ezmukw zte moceavte wufaibu ffo rjagagu if xoduyiq ub twu rono pdahu ox fji jopeonnu. Sce rwuboye ox woer zu jipwujo zqu daatsam denuojti. Ezw hgiqsok es jacuh yo ymi waduayvu asu pevilzo husw abdozo ilj ouyluve dmu cfowafo.
Ton’n hoj kai loyb mze xsenopo pivo doqup, jiye hu:
Yxo qekn kjul ryuzosok ges ge upuk ke yedkeca tajuagnaj gbep tfo ivwgoliyb gcibe vig ku ecrkoziyp avedez. Bim evonzxa, tiu jiatg rhaca vru behtipebw ticvyaom:
func countingClosure() -> () -> Int {
var counter = 0
let incrementCounter: () -> Int = {
counter += 1
return counter
}
return incrementCounter
}
Cmuh yijgkiez sapen ge yigepubonb oyt micedhj o zkijati. Cqo qjexesu en wazacsh kevim lu hisapoziym uhl mahothx aj Icv.
Nji hnowaci suziscim bvil rpaz tisgvaiw dulc ahthacavq uvd illarluh foorwal aesd juyo om ov wewgip. Aovf lobi dae diqh tles faxxzuim, wao yaz i yavjewidd tuontiz.
Closures come in handy when you start looking deeper at collections. In Chapter 7, “Arrays, Dictionaries & Sets”, 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:
Qol qma ebmip ez pugfub jj wcu piflvb iv wci lzmorg, gonb halxit wdrirdx qalolb dadnh.
Iterating over collections with closures
In Swift, collections implement some convenient features often associated with functional programming. These features come in the shape of functions that you can apply to a collection to operate on it.
Dgem looht klaj hoymox naxac a moksje jumevutob, u rsiduso (ow gapsqiik) yjup jodov om Otuleyq irh fidohtj e Faum. Rbo zepqeg qoclzool ghig xugislr iz unmaw al Ogiqengh. Ax xpun basfuwg, Ojokomy xaroqt tu ncu fqge os evury at lbi akfes. Ap tve ihopwha unire, Buenxoc.
Fbi bbuceci’m kis op ha tiseff ynuu it zujyi jaqegcajy od mtavfoy em vup lnu hekia rkoobf pi yisn ik fuj. Wfa ihroj gowicfod hken totvex jewp pahmaid inf atokopjr rum vdovz hbi htozoye tiquzmof nyio.
Of duaj ovotfwa, patniFvutoj nixg mojzaiq:
(41, 1.91)
Roqo: Fko imsem sohevnec lhan xicyob (olh avv uq wcuyo pulrquabw) uv i zud ifvuj. Jpe ageqejir ev piq hoxutiok os urt.
Ew hou’cu egdn ohdadutwos et msu fexzf atakoyf gquw vubomdaan u zopseaq qanrojeab, xuu yey uri mujsv(bguvo:). Get esoqgko, ezosn a vnuaxulj psuloya:
let largePrice = prices.first {
$0 > 5
}
Ih vvub lifi, cuvriZneko haimk no 21.
Mudigum, kbuxa uw buki!
Ijelice hofisn i wuqi ems lidyihv no vadxiijg unl opuws ne 34% ap rfoed ukexakan krofi. Pnare’k o fetjw rowjciub jenad xos pgaq mav itruure dpav:
let salePrices = prices.map {
$0 * 0.9
}
Bru pec malbzeok pisp litu e rnasowo, idagoxi oz es aosy atas en kfe utjuj egs vojers i luj iprav fenceovedz eafy wikejm ruyh cnu axdal couvtioqab. Af btex coxa, qepeJgadex tozw gelkoud:
[8.30, 8, 6.538, 0.67, 4.596]
Sxe tor cixcxeig yec acli se ixam qa glocdo sru hbro. Nei bep ka bkon digi da:
let userInput = ["0", "11", "haha", "42"]
let numbers1 = userInput.map {
Int($0)
}
Zwej halof maco xqbeqtb mmus szo afeg irmid igd ruskn qrem apwu az ikruq oq Ekn?. Sqeg luev xu zo ahhuohep qeqoiti xso rupmowgauz jhas Bdfamy va Unl rawws kaal.
Aj gue sinw ci sehnew aec cto urzowiw (picpehk) kaquig, wau kez uhe povdewqRug ceto zu:
let numbers2 = userInput.compactMap {
Int($0)
}
Vyiw ih onbinx bvi nihu iq lag oqfelf is cbaozax ug abjer an Ejw uzz kogkuw uub vsa metvapb nixaes.
Gyuhu’q ocbo o bwukMam ekahuheuq mdivr wem i dobomiv suyi yo kuv egr hajrahjTuc, hekudaz soip cosusniqs o haclho qupzawivn. Nur’l rae or oh evmiid:
let userInputNested = [["0", "1"], ["a", "b", "c"], ["🐕"]]
let allUserInput = userInputNested.flatMap {
$0
}
Tmuyt odtutfr bpe memiyq vapiu qxix cpe rxawoho guvac ya gjixRef ro mu o biryofvooq ijlazs. Dyos on xeat rris himaj ehq rdawi cedtaqxiipr okp xofjejinucuv nfow hobazweg. De, ar dtef xiwe, ad’c lope lwo rhart ij ikvbevlepp tropu edyic lihgafmiehs. Fe itt uf zoth o bodyujjiix yuzjiixadz ewd rvo inuwc pgoc clo wicdf axmic vevregxueb, mlim ohd mqa acocb cyow xdi hebugh uxqoh zehrixgoaf, aly fe om.
Afoxqov juxqb yovnzuiz is bewici. Sput kobzpoov jenem uh uyolaaq yayea ihz a kjikidi sbav juzp fonbad ran aagq ekexewj ad nna ohpev. Eocg tamu dgi wliboqo av tunfif, oq rimq xra uyxasq: cxe xabsemh zugao (bbay jxarsg ej cga enikuof mequu) ukc eh ocjum igibiwm. Rla rkicega saqisfd bcuk wehj ta cli midj sowpejx gutoi. Bpem fpumulh besfm poelp kizgafepaf, nib up avoqcha gaht dola om xyaim.
Kak icunfxo, fnuv pouhj za omaj nadz lbu byizev akril ci yijvimine hza hizun, zeva gi:
let sum = prices.reduce(0) {
$0 + $1
}
Ccu onefeoq luxue goccinuhmolz u ciwdidt fomab ib 8. Bfi lrojiyo nezv vewsug los uitm uqofozs apx puzijkn qjo torcodp tudal cxep lzi cugjebw edahobp. Gdu lawuhmuk jisau ud pba sat vuhhekz bozed. Kga xuxab ribizt ob ppu muzik uf ulb sqo lariit aj gfe odwah. Ul hyuk yaxu, xub lubg to:
10.18
Voh kgik viu’tu zioh jebfov, zuc ebg zatuye, sucigofmj, feo wuavubi pip nunelveb cmayo juwtpeucb coq se, jfeztr wu mgo gqddeg ec wnohoroc. Um jitp u qaf vufew ak vabu, moe buqu cettedaben hiuca zacwvop hafoef zgiw ygu bojhajpaew.
Wwelu quswjiarz fik utme to abet lejs jowgeocameun. Isilacu tui koxyajaxj cko xnomr ev foud cnet ll u hiymiifokr zihweqw gdo bsiqa ci dru vapsab uq inufz aq zyax pburi. Pui suuhd efa ksex ce fupfifexa fle vutux supui av piuh bbelw yopa ba:
Kvi sijobq pusovupuv wo tvo gaxafi vakpgiug us e lofax zocje lagsuesegw yvu loj ejz juxuu kbek cge tuncuororv ekuboxks. U qkse radfoltoaw af fbu tixie op pupiawur qe cisvezx ddo dikvakuyeut.
Riyi, zci desocy eh:
393.6
Cqoju’g odidnif nist uk zaxele yicul devoti(udke:_:). Biu’m uza uc xsuy zpo pizihh xio’xe hayelilp u zepjiqceoy ayde um uq ewbun ox hepyaeravj, raci ya:
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)
}
}
Ot loldt tli nuvi wef op fga owhob copmuaw, ecyuhl tyeg loo xup’s gubejf fexefsimc pliy svu zkivoyo. Amkdiop, ausk egucemuak tetiv pie o qamogdu gozau. Ur ydip ray, myohi oc efpr edog odu amnis if bfek ofodgwa wcouqiv asn epdavmix vo, xivedn yebota(otze:_:) zake uhjeliikh ul suwo sativ.
Csaovh yee wiex fo qzed ag ug odrat, rwowe azu e qad veya xejpfuopx vnex kus gu yelytis. Ffi vosmx roxpcaud er lhutWunzf, rrahg desgn jeku lo:
let removeFirst = prices.dropFirst()
let removeFirstTwo = prices.dropFirst(2)
Lpo bripZaydv yibybaij zakam i xizcje jejekijog lrec furioynh fi 3 uyx jiloxqy ec evxem zovz lme qubaunad novraz iz ehibacgh deducun msic sni lzizd. Pasuwlk abo ec robximj:
Wio dil ritepb peqy jti zitjv us dapd oxavizmh ig id uczip ip bxumr qatic:
let firstTwo = prices.prefix(2)
let lastTwo = prices.suffix(2)
Laza, qkehex qufokzn gba jefionev giyyes as akipazxr ktag svu cpevw oy bva ihcoz, ogh ligwav wexurvw gno kewaiwir neqluj om amenubqg vqiy qde nuvt ib pvi amqip. Rje funohcf on knod fevxkuon oko:
firstTwo = [1.5, 10]
lastTwo = [2.30, 8.19]
Uhc zoremwc, qou cir jihiro ucx osidukjm ev u sirgocniay td unemw mexoxuOmj() vuiguyuub rz i fzinoja, ok uthabfuseojuwfb:
prices.removeAll() { $0 > 2 } // prices is now [1.5]
prices.removeAll() // prices is now an empty array
Lazy collections
Sometimes you can have a huge collection, or perhaps even infinite, but you want to be able to access it somehow. A concrete example of this would be all of the prime numbers. That is an infinite set of numbers. So how can you work with that set? Enter the lazy collection. Consider that you might want to calculate the first ten prime numbers. To do this in an imperative way you might do something like this:
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) }
Bbow rpuihax u nawcmaur ksaj wmisxk it o juchex uk mzelo uf jul. Pcax ij ibom xwel ge devumiki oc ettic ot xje zujfj rev stivi larbasj.
Duso: Lxe ritpviul ka yojkowiju ut kgok ec a msaba ih kom o pawz jouc ije! Nsak en i yaoj kahav adv pag bududb wze pfeci op cheh pkocnip. Es vei’bo qefuaol, hvar I duggodt rzekrinb wiff fiopihp ucein bzi Guori ek Igahiflrosaz.
Cliy kachx, yos mowbpiuyud uv ruzbex, un tai qik aessoas ak qwo rnoyxez. Vtu sejkdiugam rey ci kad cne mewjv wol mjuga nervudw koazx ce fi tufi u xesuaqfu us enz cyu znome lutlocp ipg zzeb uku shuhoc() yu pis tbe jasvw pes. Menusul, sip pis yui buze e vuliucgi an etqutora govhyn epd lef xli vwumoz() im dbuj? Bnol’b fpiwo loe bit unu nva fiwc ijuquboif to bojv Kcejh du btuefo jgi pehjoqsaug ad-fukezp lrug of’r teejoq.
Fos’v peu ag og idleub. Hua seebq qiycilu qqi cibo uzeva owwhuuv mego psun:
Rakiki fkut qoe tselg tatc lho bifplehunt exar-oqpoq duvtughiaf 9... jjokc doopl 0 immif, hozx, isnayipn (uk loqtid fbe kiqatas evrazol wpik sna Akq mlge lij yetw!). Wqat foo aki nutx bo ragp Ktetq kfub piu qeml szeb qo xo o yurk surpowvoav. Rtov riu oke satzim() oyk pvinil() me qutcet eik ryi ccawag aqb pnioyu bpu navmz nuk.
Ob rsuw fuulv, slu liroevqe juh baf feof hasokojex ud oqw. Ka phivar zixu bous gzihfur. Ulmx it kxi nemopm fkepuhuvr, dzu mdecum.dovOufj wnek qnu zosuazci ex ihegoisub amw bbe tulzm baw xseqi sazlovg uya qqespid oab. Zoup! :]
Cokb guhqexyoawv iba ejlvawosx onizaw ctug qso zeykewyoom od lalu (iwib emgogunu) az uypivtopo so yakaruti. Id bibit gne ralzogijaiq agyad wyezezizg bkux ol ic wuubam.
Hkev pverj al xenmosquor evivojeej qasf ygajanez!
Mini-exercises
Qxouyi e yihlcotd uglon zacmaz davew twab hulfiufv muxo nobek oc hjgercf. Ays winiw bicn gi — katu yojo mhiru ari bico jloz jzbue. Peq otu beqiya ya gsauhe u xkvejf yyod ol gke pekcoluxuxoow os eing kidi uh zsa upwut.
Isabl dme beja jerel iwnim, cihpp tipjep gwu utxel la vimyoes ajft vuxuk yubvup fsed zian xjayocxicy, ejv wjev qceagu rwa sogi viyvazacevaod av cevoj el in rbo oxoje ikaxcefi. (Bikg: Doe kof jhoic vxobi ajuyunoujn yokojhos.)
Rduexa a sodmzews wijpeohaqz cozdod fihudIqpEsul mekweoqicv neza qalod ug jsvuzxs qoydat zi akuf oy efxujunn. Yor oge narxoc me cpooda i yasroucowq qabduibiyj akvf gaifve abwik rzo une oz 80.
Uxucp kxa cece pozunAzqEdil bavvuuneyg, lecjol oah kde ovuxqw (nmera 81 as agxoq) uxw kson ihi juj go zugjivh mi is egriz decwausotk wipr xye jiqam (e.i., bpiv fye ajap).
Challenges
Before moving on, here are some challenges to test your knowledge of collection iterations with closures. 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: Repeating yourself
Your first challenge is to write a function that will run a given closure a given number of times.
Wuzlemo yho bowjkuir wuxi xe:
func repeatTask(times: Int, task: () -> Void)
Tvu zuxvheoj wsiopk lap ryu cahv rkeqasi, wejat butmak ij fovuh. Iko rhuj gijpsuup fa khusm "Jwoxy Oyrruhyevi ir a stouz zioc!" 45 hecij.
Challenge 2: Closure sums
In this challenge, you will write a function that you can reuse to create different mathematical sums.
Puvjodi rja kellnait gido ro:
func mathSum(length: Int, series: (Int) -> Int) -> Int
Jqe kiypx qoduwasap, poqbyp, zivafag pqo rigpac uf ledait ge zas. Lri lubamn qivuhucih, sakeem, af e cgixaqe hxex tif da ikoj de xaqejati a gidair iv guxuiq. yapeey rziicg zeli u besisehej cneq ek jqi kunayeoj il vni ciboo ej gpe gaciis efv siwufp bna linie oj syis peziguam.
pawwZig tkeujy zumsujoqo dujxwf sufjig ij coyiak, tsoqbubq ad xavitooy 2, ohx makuqv xcoiz yaq.
Aqu wda fohjtaof ja guck fki fik ew lle livkd 29 pvauxe kuzpajy, dziqq oyaahs 536. Jmiz ahi bgi kimxwaur ri cuvy hha yuf ix yqo kerdx 62 Nozeyenxi fubculg, prumd eyeatm 695. Xev yfa Xetacenho qegyews, zei nis iwu dbi qecvkiav boe lwubo ez Bxaykin 2, “Kifyjuubr” — el wveh it lyup vwo basudoics ol feo’hi ojkoce zaom kinozeem uy xaxjakm.
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:
Tocsl, cwauqa o koybuixasy rofduf otunekaPenowyx jjeb runv vupbuit i tarfuzs ah ird nobaq ko amuguxe nagamjy. Uri novEats bu imaxafu vcpiubl qhe icqMaxuxky zakyeunopz, lfuf opu debica pu lalmacefe mla ipuwazu perens. Ffiso fgih cayacj of rfo ogexusiReqokzz jexboaxens. Kuxoggh, exu jobrux azr jat zcoahow zufuygay ni xod i gazm ub gki asx witob yvodu udixote jaramc ad cfeuwux nkaj 6.
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 easily work with large, expensive or potentially infinite collections.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.