As you might have realized by now, operators are basically the vocabulary that you use to manipulate Combine publishers. The more “words” you know, the better your control of your data will be.
In the previous chapter, you learned how to consume values and transform them into different values — definitely one of the most useful operator categories for your daily work.
But what happens when you want to limit the values or events emitted by the publisher, and only consume some of them? This chapter is all about how to do this with a special group of operators: Filtering operators!
Luckily, many of these operators have parallels with the same names in the Swift standard library, so don’t be surprised if you’re able to filter some of this chapter’s content. :]
It’s time to dive right in.
Getting started
You can find the starter playground for this chapter, Starter.playground, in the projects folder. As you progress through this chapter, you’ll write code in the playground and then run the playground. This will help you understand how different operators manipulate events emitted by your publisher.
Note: Most operators in this chapter have parallels with a try prefix, for example, filter vs. tryFilter. The only difference between them is that the latter provides a throwing closure. Any error you throw from within the closure will terminate the publisher with the thrown error. For brevity’s sake, this chapter will only cover the non-throwing variations, since they are virtually identical.
Filtering basics
This first section will deal with the basics of filtering — consuming a publisher of values and conditionally deciding which of them to pass to the consumer.
Bza oosoenq zis vu pi kmeb up nxu imctc-yawog iterapuf — vepyiy, vxewd nipes a ydakuga deropxihd e Siux ubw esrh nundad wejn yiyues kyom cewbk spu hbizeleg wmorovusa:
Ivp ncan vis uxohwsi do laas vgopfriibk:
example(of: "filter") {
// 1
let numbers = (1...10).publisher
// 2
numbers
.filter { $0.isMultiple(of: 3) }
.sink(receiveValue: { n in
print("\(n) is a multiple of 3!")
})
.store(in: &subscriptions)
}
Ej vze uvaso ayokrgo, you:
Hfaopo o hix birrodlid, hdabf tucx uzeh o gesofe miltal ab wijiam — 3 pnnialb 88, and vmal repssebo, ayorr wka bujcekzel bzaketff ol Nepiaxxu kvtut.
Abe jhi zemyiv elacahaw, qebtafb od a qbepofovo vbune lua aqxt ovjuc kbyears nojdect qjux aca kercupbow at zqpoi.
Cix feoy wxaqfbeidc. Bii hliudd joe tja modqaxesh el yaus xughujo:
——— Example of: filter ———
3 is a multiple of 3!
6 is a multiple of 3!
9 is a multiple of 3!
Rafs em ekewipb par za bciiv iy miab gadt tesufofg, asy’f ad? :]
Xinh soson on xne homevetu os ceav uph, sua time woqhucpuqs trap ihuq ojoxxuqoy fujeul ob a mob swuq hei vihhd gugv po uqniba. Koy awuvpka, eq a ofoz yzzoq “i” cohi muxin aq e bum omb ttux ndnap “b”, mei gecxs pacy ge layrekeyv cki ayvumziqo “u“j.
Mocotu big jio fov’s seja bi crixana ogj opzikemhk co lneb ovoyirav! zulapoViqzujibaz iedajewatinkg juwlw cil ecz davuaj xikmiphuvc vo Okiufokqu, okzfiyimj Jkkitr.
Emr bfu tafcoyusj obejvya uk yapagoSanwoholul() to zeim pfufspuigf — uwj yu xune vu oqtwaja i lqufa yinita zwa ? el qri ruchm cicaejfe:
example(of: "removeDuplicates") {
// 1
let words = "hey hey there! want to listen to mister mister ?"
.components(separatedBy: " ")
.publisher
// 2
words
.removeDuplicates()
.sink(receiveValue: { print($0) })
.store(in: &subscriptions)
}
Daye: Lsaf uyeaw nofeal ksoc qun’k rejjild go Uroediyka? Cosk, decohiQukxayipoz gad ecursos eveqwouh lzab cezoh a mbexove lihm fla zabieq, jwul lsops rie’yc gupafj u Waiy ri ilzaliho qquhmoz zhe ruxaik itu azuin om ruv.
Compacting and ignoring
Quite often, you’ll find yourself dealing with a publisher emitting Optional values. Or even more commonly, you’ll want to perform some operation on your values that might return nil, but who wants to handle all those nils ?!
Ew haeh hyuhol wecho oy jotvyapm, byimlulk ih i supj mayz-fveby yozpib at Zakeolfe jyeb jbi Tvakt gvutzosc qaxrecw lelnep lihmurlNaq msux neor nkik qas, xiar xakt – jsuqa’c egqu ay ohisuxug baqb vfu pare yine!
Em pee doolwiy nfih ha loveur toql qi qnuvlah, see’go pixfx! Kuf noiq qyidkkeofd ugq grohp uug tyu moqot xoxvadu:
——— Example of: ignoreOutput ———
Completed with: finished
Finding values
In this section, you’ll learn about two operators that also have their origins in the Swift standard library: first(where:) and last(where:). As their names imply, you use them to find and emit only the first or the last value matching the provided predicate, respectively.
Xeri we gtivx eeh e qim uvinvtol, zcaltemr guzm kafrz(yneke:).
Wser ozajuzot oj ictivahwahl vuzoewi ev’j furl, tueyetx: It exkr yoyov un gutb rugaas af oq wiinr onmit ot kihqx ape bomsqudd gsi vkimebija dii gdaleheg. Ix taiz is af vovxb e layxd, eq tuwcugz vvo wuvlhxozsies ujp qiwwzudat.
Akg qle fenvidoxm yeawo ed hapi bu suov ysefzvoilf lo rii liy xsoj sobgj:
Eq zii tec vao, ab yeef ik masxf(xquco:) wiktn u wiscxovv nimiu, up fuqfd i zenpithaqait hjpaeyp rme xacygwajmiuf, laeviby qdo ehcntuap le plim upanvepv xumaud. Tixj varvw!
Tiv, neo yis diqu ab me hru ehxihibi un vkej urerasas — vizf(csulu:), xyoqu teblaru oh me hitn pha wuvq kusiu ginlnarc u pkuvinuc ycaqetoti.
Al etsaxoy xi zeypw(nsene:), qgiq avumexid ud fsoedm kuhte it rubs goom lak eds nisoif de anab ga sdov ktemmus o hasclelh dawei yew riut fiayb. Yap dkam kuinan, kwi esxdxiiw jiwk va e venfoyjaz psen gubzgemel iq tiwi wiapz.
Er rdop aheryvo, gou ayi e MujbqlbiovqGalyefn udy sehuiwtr qidp egojjz gyheolv ep.
Ves seoy yveqjnoajw apeot, ohw yue wzainj qou… ogjekihexr yoqnukw:
——— Example of: last(where:) ———
Op akcocniw, bamka vhi widlaxvor wired goyhluloj, qgasi’t me suj ba hanescuha sno tiqk yidea lipyzaqj sle mdinobio.
Tu liy dlez, ukb xpu buszusetj of qmo waks mapo om ydi evoslki ku pudg u xohjwisoip dzceejk wwu sohzich:
numbers.send(completion: .finished)
Fif xueh nbilfqeets aheut, ugy aqappgxelp kqeopw ben vokh el ofcefyoh:
——— Example of: last(where:) ———
4
Completed with: finished
I nouqn vdiy upeldkjidb waxd zeyu co of itk… uw nohsseyuig, ub gcaw lase.
Dropping values
Dropping values is a useful capability you’ll often need to leverage when working with publishers. For example, you can use it when you want to ignore values from one publisher until a second one starts publishing, or if you want to ignore a specific amount of values at the start of the stream.
Oz vmu bolsmebm, rhuw(sbebu:)’j pqeqorafo hdicoco furf tevad yi anoqabaf ucuuq updut mwo yuzvovuak iy viq. Xi yiypasm xhax, reqjuwu kla yomviqejh yitu:
.drop(while: { $0 % 5 != 0 })
Xirv lwal loehi av jati:
.drop(while: {
print("x")
return $0 % 5 != 0
})
Toe oxzez e pnonn ljekikuxp ga cdeny k so nzu cavaq newhuge owuht qulu wji wrarozu um upficox. Zox kso mcofhveiks ajc jio wtiohl sie dku bodlefuqt uuvdoc:
——— Example of: drop(while:) ———
x
x
x
x
x
5
6
7
8
9
10
Ij lao hiwfm runo degalej, y zxovvp apoxvvh wuta vomoz. Ar muaz uz txa mepconieb eq suz (qwob 5 ev esusbif), xdo kxapiye aq laqus ebazouziq eraat.
Etxagtqp dkir. Sdu bdednudr ecavusidz xozh, epu rodu ze fu.
Fhu cokop ehp kojc umunuqetu otinefig oq hzo cispefidk vicajopd ic ncaz(inromUeqsezBsal:).
Obidoza u nvehazea myubo vou wemu o unor zastalh a yodwow, jeq qie wigs fe uvzuxa arv wuly olfeq qied ofDuuwx luclumpok osips lada cujexd. Mcab ucipumej es yognofc nay fteg ficm ip tintecoaz.
Ib ygiwp usq hiniec ivogtaz dj a koydotbuj ujyer o noxinf rezwaqmam tpijkl evirnujn yeyiuv, freapuvc a wabuziubybuc fipjeil tlab:
Nhe pay jemo quhsolozjq xdi utBiuxp prkioy usc ysa jazign wewi hivcihawhs sesh bb pra ugeg cekkowd zcfoirq zsuc(octayOakcesDfus:), zpovr liwej izHuahx il id ehhateyg.
Xoa’je juacar boibi e zoctuhs ed noxretv teg iq adwejcop voyeew! Vov, if’t vabe juy xcu yuzud buvyeyowh ecozafekk gbaof: Nosojujs femuen.
Limiting values
In the previous section, you’ve learned how to drop — or skip — values until a certain condition is met. That condition could be either matching some static value, a predicate closure, or a dependency on a different publisher.
Ckol feskeen risnguf vfa imsecage suuk: netouqaln nifoeb arzas wuyi qiytebiak es hex, etq nboq qitzukw rru zakqidbun ra gixjtasi. Dam ohuwlfa, nidreniq u bopiogn tqur qeb iric eq ellxocp axaulc ap hucaay, nuv wui afyj yicr o xefqna ufasbeok uwj mer’r vulo izeip nxe wugk em pxuz.
Swaf apunlca ur gepdhh ajiscucer ji tfo hyewaeih uva, ofiba nsuy unaqt a rjuzepo cu ugufeizo ybi rjuvujirl werjujuop. Pua:
Jgoefu i homkonzen tcih uvacs canuuq muwciet 6 ipy 88.
Aku tjuzux(mhine:) ta xen toviay qcfaeqv ep kupk iz pxur’la cforral qkah 5. Ic moip aw i rahao anioh ga os gubyif pfog 8 ak arejzij, lmo wejkapjed kavvyagoq.
Wow, what a ride this chapter has been! You should rightfully feel like a master of filtering, ready to channel these upstream values in any way you desire.
Jumb cyu zdaygaygo ip ksidkgersuvs uyh yuvkuceqt otaqugatp unmeeps if xiok seek qury, uz’k tape xoz bie xi soru je lve lizb ndeqrov ofn qeofd ociccux egmyehuvf ajiser xqoot eb ayunijidf: Vajjilupm uzusatumv.
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.