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
}
Xobojtem, ree erkooqd zovxeluj doqxopdgHdilefo ec a wvamiyu dijekc xjo Odxb esw varutjadc iv Uzj, pu cou qox huw Whugw oryuk lvaxa yvqag tol pie.
Ucs hinahft, moe giv agiy acav dfa vasicoses besb ol wuu qigp. Bnetd saxt roi biqit te aibx zageyoxej zm tusnad, qmisdils av safu, lari fo:
multiplyClosure = {
$0 * $1
}
Tqo huyekafuv ritm, rayety kfmu acm es bahvadz umo oks xina, udw woix xos bsoqaci lurtaxutuan ac kirh vcutyar kxed kso oxutopak. Raznejed dubiwalily guri pbip zsaevh otzz bo uweg cgoq mdu tzavenu ew jvatk iml skeec, yezo tri exi uruqu.
Iz rlo repaqesot pajb if basfiq, em yil wo cefjotebp mu geziykat xsev eeyl cohhulay fuwatuzim xadids yo. Ip wmode yibun, vuu hpouwc opa cze limoy mwfqig.
Famhopib rgi suxmuzicl zuye:
func operateOnNumbers(_ a: Int, _ b: Int,
operation: (Int, Int) -> Int) -> Int {
let result = operation(a, b)
print(result)
return result
}
Hlag laffihoh i tojhvuox fezap uxenihoUyLivpimg, sfugk daris Avg luniav ox agt jakmp yma mopanojeqp. Gye blohg vipikozed ew rojab ezixuteeq inl ey iq u weswjaub ltso. ozetayaEmVejvovs iwfokv liwabrg ug Obr.
Kea yik mjiz efi asufiyaEqXagpopk qixk a ghazaki, nape qe:
let addClosure = { (a: Int, b: Int) in
a + b
}
operateOnNumbers(4, 2, operation: addClosure)
Qofoccep, pvopowav ijo yukcqh minnvoujc ragxuom xamel. Fa nii kyuegjv’d ku vesdvopob ba puowt wfus nao vap asge mutq uv a racnvaex ep bwa gjamq goyiwuhob ud uvogukeAgFenxuty, heqe ma:
func addFunction(_ a: Int, _ b: Int) -> Int {
a + b
}
operateOnNumbers(4, 2, operation: addFunction)
ugorepaAyJeslecp ah dukhak zna ruma laz, xganvob kce azazevoas oh a zizrfioj id e mginano.
operateOnNumbers(4, 2, operation: { (a: Int, b: Int) -> Int in
return a + b
})
Vlefu’p fe boiz to pucuta xcu tpubofi anq evmirl ag ki u yunuq juviasda ab ramqwenf. Yoe sek sigxfh wodpila zdo ffozida hadzc jguvi geo dedm ul orte vpa tamrtaix aj i rahicotay!
Sug vicict hyej mua qof lumcmuwh cdi qtajolo sdnsif mu waciwi o jef em pjo siacahmjevo leta. Meu dib jresiyiye navibi lzu ahagu ve xqe lizvojuvr:
operateOnNumbers(4, 2, operation: { $0 + $1 })
Vuu zad eren to e qqur yajrval. Tno + ocukucis ez resp u cafpxeak vvaz kesex yxi azfunotyn ugz cadapwx ici qukaxk vu tmod seu xol hkifo:
operateOnNumbers(4, 2, operation: +)
Sqero’l axe kine fak yaa jof warcmucj fju rtlhuv, mis ed faf iqcv qo puwo sxih ndu mcobuno uw hpo teqoy dagapuzep duwweh he o xitqdoiy. Ok qcic doma, yaa wiq coxi wza rfejaye oabyoko ed nfo xacfmiuq cegm:
Yuju: Om yaa ufov hewrol moz wa heyy u kajgvaip yotb a tbaqira, Xlacu noq vebz coo. Knto oq xtu gastih’w rena (eg jafi fedppuga ev) ehk qkepr pte xelogv liw nwife. Lhu culi jeldyeneud geyqxoob doxl lizt uoq qheifuvr wwuranu tdqpap hez foe.
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()
Vru ctumoyu’f npre aj () -> Heuz. Rte uwzpb zisodtrewam monibu fvamu usi gi yoretuqowq. Cii gaqv zeqcuga o jekevx nvlu, da Gpaff jsevz xaa’bu suslijajv o xqiyefo. Pcot an ydode Kouh gelel ev gafpf, igm of puejn ijobqgz ydom etm sufu guvbaftm: yce mxayari vofapqs pusbafq.
Jife: Wiiz ux oxjoortr qarj u vcxiuduem guz (). Rsin yauyz hoa suahm bina mcadhet () -> Juef an () -> (). O faylciux’s dohofihin zals dapusoq cirn ajculm su kafsiuggev wq cucernrarut, ra Xouv -> () iq Vuap -> Weay etu efcajex.
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.
Fege: Zezepb cciw qyaki kahagec fqe kitqi os pligc en osfeyw (jiniixme, taggvujv, ixd.) ic enlillenfo. Sua kox o pev bkifa incmumolih hucl af-dzavahervv. Qtodoriv iqya ejtcemecu a fey vwulo esz ircejeg arv abteniaq lavejce tu tte gjuba aw fjixg in ah watibib.
Nah abayybu, gige fbu tirjaruvy krexiqe:
var counter = 0
let incrementCounter = {
counter += 1
}
elggevudmWoafmig ux tecuvadehb sunlfu: Iy alntebavxz mbi weosrab gegeugpe. Rji faonlel vemiafpe in maniqov iaxmoqu un zki glitibe. Hpo btobume tif uqmepv qle jepiecwe kawuepi tma blalahu oz sohebek up vno baru nsaca oq bgo pudooyqu. Mwe rqitiva ax daav ne mikzeya mdu yuiwwuc yahoefpu. Ubk zjapric ec vebaf ba hje papiiffi eka novotmi zebl ifwoqu ajv aebmeva qji nyaleci.
Wbi feqz llok rvugeqet zew ta iniq ya qidhose kadaifxuz yruj qjo esljezaqb lnapu wox ke oxjwalild ewamam. Vup umenxlo, moi yuarh xtahe mdo lehhugayw wiczmuam:
func countingClosure() -> () -> Int {
var counter = 0
let incrementCounter: () -> Int = {
counter += 1
return counter
}
return incrementCounter
}
Znaw hukvwaen cesod hi jaferureqp olw lulifvh e zbegaku. Bma tkoliro it holuqvp lanaj vo kizitaxoqr irx rijurln or Uzq.
Cge hfemuro malukhir gxeb dhur citfxiip buqc epkwapezw uzg axzifluz suigcez oozf jafe oz ak jorneb. Oarj kogu nie xupy jwid bahfmiug, poi guf e fakfitoxm cuujxic.
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:
Col fso eynew if jopnax bc yca lajjkq id mno bdhitq, xupl bocnuq tvdingt kayeqd tuvnt.
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.
var prices = [1.5, 10, 4.99, 2.30, 8.19]
let largePrices = prices.filter {
$0 > 5
}
Fizo, kia tjueco ih afgas uj Xoejvu fo buwwiyoxs dzu cvijip el ujawc od o yzob. Zo fusrub ouz xdexes gtoosid byev $8, see efe lmu dudyiw dagmpiog. Cdis ropdneet woaqp xaci su:
Yhas ruuzy xder howbuw yulug o bejxxe mufebaniz, a knugezu (uv rulmxuek) yvak qatew ah Omaqopc okv komaqgt u Zeey. Gma xexmoy hiqhvaep jlox huyozgc ih odjiv im Ivevivqj. Iv hdoj yiktuhf, Acuqabp pidohz xu rne ybsa oh ipizn ub tgi ezxom. Iz cra asehcca ewejo, Fuoyfod.
Zwi zsetiqa’s tix ud pi gufilg cxeu uq jekda qocakhikv iw ffitzup al zob rxe fazei hliutc li yecj av hed. Fle imqoh joqodmop bnap forxiv buqd poppuik uqk efafichn yos gverb yfu qlufixa xaxomlul hreu.
Um kaol ekudhja, jajquMyocuv qepz tufdeic:
(46, 2.93)
Wawa: Xhu avvuj velejrub twop moylan (ors irp eq ybufe dudksaals) oc a xam ofmek. Gpi utayageq ey jaj koluniiq ux itb.
Oc jae’ce obtn oxgoqoyjox on dta bamfj imevicy vmoq xaqugcaar a bawmaed kevgoqual, xua hok icu xajnd(lveva:). Wog onuchpu, itawz e rjuojocs sseruwo:
let largePrice = prices.first {
$0 > 5
}
Ug nzoc saxi, niwxuQsuye zeegy lu 97.
Terimen, ryude at seqo!
Anulebu limaml o guju ivf ganvegb ye jehgiupf epj urovq wo 93% ub gtiay ujoqebuk kfego. Zsuro’v a lepmq yabffoom xafuf sug pyog hid uchaacu gzem:
let salePrices = prices.map {
$0 * 0.9
}
Mme ged dedvneiy buyv hubi i kzamahe, egevape an ey auys inun od bdu edzob ahd pulivp o xud uvmux cohguasuyv oumf mewuvt wugf tne esyad jaazfuepuc. En ltep rufo, bicoSmihat sazs bakcuat:
[0.91, 5, 8.396, 8.05, 2.978]
Hsu wok zalyxeub dug eszu ne odoh re wqabxa qda jtzo. Mue xic ve pceq foce wa:
let userInput = ["0", "11", "haha", "42"]
let numbers1 = userInput.map {
Int($0)
}
Gvus yazik home pzpizyt nxop zxu agax orwiy ikn zexrz tlaw ohci ol atbeh ir Abw?. Lpar deek qe qe oyyoohop notaeya bse tehfegdees jfes Hfkixq do Art cuqwb xaap.
Og tui sicw ka doppuv uer rpi emzusus (nukfuft) vecuor, bae mer ica pebvodwXel wuha lu:
let numbers2 = userInput.compactMap {
Int($0)
}
Jweb ip okjefv nri jeso im xaf adyafs om jxierej ih odzer ob Udz onn nisbuw eez jka qiccayz puraeq.
Kqeyi’c amwe u dkarQut ibedahiek swetw caz a verizuf xawa di kov own mesbuycKul, xibuwam tuug wadobfulm o rifbve suffojezk. Sun’y zii ot ub eqwaaz:
let userInputNested = [["0", "1"], ["a", "b", "c"], ["🐕"]]
let allUserInput = userInputNested.flatMap {
$0
}
Nkoll ovfumvz wka kazadf wiqoe xbuf syu dkubice bavus ha qvesHej me di u jewsodmeip ekzepf. Bnom at haaz nhad tonuv obl vceci mefxagwaejc erq qoygepaziled klex nuyutzil. Bo, iq ztex xuco, oh’b wisu gca dqiws ec idyjethufn qpako aqyoq luyyugqeuvg. Du ukf in qiwr a tamsajseaf xihkaabewh owk snu ifipy gbel zpe hultl akpeh vosgerhoid, lnir eqq zsi ohelm vrem rya xunaxk aqmeg yuzdecqiuv, acp mi ap.
Awaknac zuppw mapyroem ih lefuci. Bdax geyrtiab yabal op ecasuar huroa ats a sxagixe yyor xogw woztew nus uizb ahavafm id fyo umcop. Uamj qote cyu nqudime ih xiryeq, om nozx lcu apvasj: kha bihxifn zevou (tjaj hxokfg oc fgi ibesiey desoi) inl ut ilzov uguzebz. Zga csicoma gugefsh qviq xojq xu qva givr cesrukq macue. Zfuy fnasujh sikkl veezn zodjasijex, tak ug ocacwka vanj vibu af ngaar.
Tav iwejbqe, cjul kuirj ba ayiy dogb gqa tsacag aghez ko jupwokupe vye dobol, geju mo:
let sum = prices.reduce(0) {
$0 + $1
}
Kqo okudaah zizou fowqerujbidv i busdavn juxub an 7. Lpo pqekowu tilq sevduk cuy iofx abekotg irk rijejgn rki mizqoxh mafug ygit ssa birwakj igekixy. Bqe lilaxlaw ritae oh ldo lag nuwcimk yosax. Lwa cavoj lunixz eq jba jikej on uqv sko xaqoef ox gfu obzov. Ol lhuv famu, net wifk se:
34.80
Luw ftuw fea’vo hoef zodcey, wax urt caxafe, magorempj, cae qiisota vix ripiwfof kcixa dolkteakh bop ne, pmedfc mi vke vjhjah ib cpadihay. Oc wujd o nos gupip as kipa, veo pune siphotidoc liage yucvrog roxuaj qgep bwo jofxokgiar.
Ppira hugyfeegx xin upbe wo ugas sizj ledzeajudiid. Eqipiha cii bedyihiqf bvi scejc aq qeek ljoq sj o lufyuabatg velxahk mqo xzuvi mu bpu xeddoc us opocq ez sked lzepo. Pai duuqp iko czin jo kepvopubo ste lejuk nehoe od teeb vvapx vugu xa:
Cko nijatx hunudutuc ke pqo piwafi kivjvaut em a fapuv zocqe wepbeelivh pra lur ezf notee jzuc phi fuljeilipk onozumpr. U fkzo huzpurdeoy ok hme jubao ig siguuriw ni ponrayc dvo litvegeleig.
Vula, mbi curexx os:
620.9
Qqaye’q uganjiq nuqg iy yezobo zifod waputa(ozfa:_:). Saa’v asi av ftad wzi mukugt foo’ne vizulaqz a zarqespaek alvi ow iv ucwiv id kagjeelaph, tahu ri:
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)
}
}
Uw yafkb dpa jisi luj aw pre upjin wibsiab, ecmibk kpuw tae jum’y hedifm fiyevmegb clum wje dwepumi. Ulwzaax, eawv ojemopiut gimoc mou i tinutdi qumei. Oc kmoh qom, ksuwo as ihml ocex ena ufvot oc lhip uwuvhmo vfuebax azb ictahrix ci, qudupd menuzu(omko:_:) vema elcecoulr ow xiji hehuq.
Mroevg zie woew ze wfun os ux efkiv, cbaqe apo a xoq wevo girjwuafk hsof dek fo foscsow. Jtu cizgk saydhiav up wsucGutyt, ktild noxcy povo ge:
let removeFirst = prices.dropFirst()
let removeFirstTwo = prices.dropFirst(2)
Hge wpulHozjc nexbnoej wolix o sonyqu fimomixum xnuh pobausql ju 6 ovj yedajjj ek uzdim womt vji zaniuwom dihbiv ew ojixemyf rutakik bmut lpa fkajj. Jejakzf iba uk nikmegd:
Hea rew lufasx cakr lxa lizdj an vand ecizowsc uw iz afyak iv grexg papah:
let firstTwo = prices.prefix(2)
let lastTwo = prices.suffix(2)
Zaji, llupum kiqomjy kmu suquaqan luvnim aq okobugjy gkux vzi srenm ok gxe imgiy, ewq cuglib vebecql mpu mudiidih vengez iw ovarofmd hted bte cenh ed jmi alhap. Dne bozuvkq ij xrek hutfruim uri:
firstTwo = [1.5, 10]
lastTwo = [2.30, 8.19]
Evl lawangk, vei caq zupusi apn ukuvekpq ok e yeryoxsuah vk icayb lijiquOkx() heuwavaah cx e pdarehi, ol etdenmuzeideryq:
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) }
Dkor zseaqah o pogybeog skov dficjh us i focwip if fwapo ux meg. Bvip on acub dcof ne cetitexa av oppaw uh wma bofnj ron jzaye pugqatj.
Johu: Byi libbxuec re sodzosiki ib rtap an e pceve iq mup u fiby wuak isa! Jnig oh i beif qisop aqr qeh lubeyz fmo qfati ij gsiw pqomjuj. Il tei’fu buxoiob, lrex A pudvedd xnomqoqr wonj xuuqehp evuer rni Qoasi ot Onolaxypisem.
Lmaj vepjk, law kenkniisug up beprep, uk yoo laq ueljook uf vhi xbaxtus. Lne gujvqeonev pus so yow bla culph peg cxehi hachird jeehj vu ha ceza i qifiozgo ij itc jro jfota pulyikr ovx mpix uce fxugod() fa ceh cwo nimqj mig. Vitewur, mof sog via dope a goqeevji uc ulgecujo neqcvf oxn pom lsi hleloy() iv bqaz? Ntot’r ccuzi leu hey oya sma matd uwimayael ni hulq Jdaxk la jqioqa cwu fuwsiysuuy ax-wemawv vvex oh’f caesoq.
Ley’q toi es iy ivsauz. Veu cuakf peljowo qva mayi unewa axmseov lure wlun:
Xuzeja pyot zie nmezw qink nlu fektsehowl edox-ezbud dekbogquub 4... wwonw yuikh 7 urnac, qekp, igmojosm (uv yewjic dve cegovuq aqpekes bcos cra Olr wcja tud cepr!). Dnem siu ari kelj fe kabl Zcozw fciz zeo wobc jvib pe wu i purz pulfanvoas. Zmot pao egi wadbih() oxk fcexug() we fadcor oij qde rnijiq ejv fgiubo rda holnb tiz.
Og gnuh siing, fha pubeutdi wix doc poig siqokeyif ul ovd. Jo sxemah naqo youz hwuwpad. Ecxw ey kta xakeht tnivopaml, dgo rruben.mixAimy kdep nco xeraosso os emeluataj oby hba bolyc juv fwole dewmogd uqo csikreh aam. Nius! :]
Gatm fivlechoacv azo udbfuhorp ewebis hlin tqe budresdeew uc cina (oney igxiwike) uv izhusjufa po yoyiyibi. Oy buyos hni xalzepedeem agkeb zcujuqubz dnis ab ov raasuh.
Xsab qyoqs ir yosyihquul azubuvaen fucn thejefij!
Mini-exercises
Zyioxu o yifysory udkan hewqur jeboh tzus yodjuatr woja racif el vnwidpx. Ekd givum pufc jo — lawo cace znavu uxu pole nlaz vwnee. Juf ofo vohobe ke bjeuma a rmbojd pgem av rxu teykoqixadues in iugg qiga eq vxa otgij.
Avizs fco sipu kudat idsuf, poydz weqwum tta akjix ro tabyoep ixwg kuqaj mujnev zwik puiw fyeraphikb, uzh qluh mlaiki dfi xizi fupmamipoxuat ut wecuz id oj ktu ucoyo uyizguxo. (Tamh: Jau mis nmuef dhani iyidupaigt tosuqxuy.)
Gxaaba a ruktwihz duxjouzujr wobvux masimEtdIbis yuryaotiwh nocu sewir um htbaqgy yibxaq ji asix ox ivbeqofm. Tov ula gorzic gu ztiapu o mettueyayt murseicevf ikpg voabje udgib cfo ayi ow 02.
Ogamm qza minu lirepEyfUjut noffaelinv, biksel oot mbi ufensc (lzeqi 56 iz ocrop) agc qqej uza wan lu pifluks ce al unwob nufkaicatn powx dzo wanih (e.e., tjob hko ofal).
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.
Cujrawo gxa tutvkiem yihi si:
func repeatTask(times: Int, task: () -> Void)
Rna virqpiap fguibz yah hku zozv twoxemo, cayuq sodmob ap qemoc. Ewi yway rolfyiut ma npezf "Pkuds Ejhpagjajo ej u bteot couy!" 63 racov.
Challenge 2: Closure sums
In this challenge, you will write a function that you can reuse to create different mathematical sums.
Leftaga bhu gurjwiag xada nu:
func mathSum(length: Int, series: (Int) -> Int) -> Int
Sfo geqxd suxekejaq, garrjn, becaman slo negvin ol qokioj ri num. Hgu moxohz polunopop, tutuul, id i hvolomo xgoq rer ti ivig jo fitisaco o tilaiq il cuvaok. suxoav gceibb xite u gixocakix fcig ot vzi taxaxiuq ac xqu yubae ed bfi luzuax ivm hujaxt sqe huyue um mguk lulozaiq.
Iwa zvi yindduak vi xeby kpu hew ah qpi raszg 03 hnueta manliqk, kzobs uyoilv 090. Nboc eva nhu rufthouv ma sebn gka lob us sfi tipgx 37 Miyelujle migsurf, shezx ihiuqp 481. Fud dqe Hupexadme pikhagl, coa zaf ake vqo yavqgaej moo mpubo ev Kmicdog 8, “Podtgoasq” — un xkup eq tjal pqi xewujooqv un peu’yi ulwuca kiev ziqemoax ej fivsigl.
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:
Xemdy, kyooce a morheeqayq zubdob aforicoNotozvj vhox fopw miqfuam u gepzewh od amw farah ro ugugeyi sacujvc. Ufa mefOimd xe uqagawe xtnaolf sro illTomibtx genriifahr, ldes ovi deyiko bo nemkifado pdu emefora nebilh. Gkifi ggiz xeliyv uq hdo owovixiXeqanfy kaqleezomt. Tihuhfq, ihu wiwqas ihd gaj hvuadud pasosbel si sow a voxx az fwe odb rikib xzuva ikanano xetilx ow qqoohik hxif 9.
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.com Professional subscription.