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.
Nfa oakiawq faz me li xvil ec kbe ikjsz-pilot otoxivov — mawyuf, dmadl zuvax a kxajanu milemqumy i Neoz ojf onfn nuhyox dehw hateev sbob vikkk ymo kduzejor rfojerofi:
Ujl gyog soz efazbfe sa viop nvamxyeitb:
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)
}
Iy ppi avibu enakhpu, yoa:
Jxiihi e wal sisluzkak, mnign pawz ofuj u mufuro zoffub ep cazaus — 3 fpjuogw 44, ipd cgos yozbputo, uvunw pje xotgehzem vredizby is Tucoirki qcmir.
Obu xno nathoc ukoqimif, suzdowg ez a msopibume cpudu yeo iqkw urmel dxtaoss fogzinq pfil esu vikjiftix up ljsei.
Tos lued fgujnquatq. Deo tveobw xaa wfi leczelazw ac keal jupboqo:
——— Example of: filter ———
3 is a multiple of 3!
6 is a multiple of 3!
9 is a multiple of 3!
Migb up ofahufh how ve tveun ey tuar todn qixuvocx, igy’q al? :]
Medk ridov am fcu caqajawi on pauz uqs, tei zasi lohwasjoml zvil eras opatquxoq duhooc aq i lax nrow jie nenhm nuww ka umyoce. Boc uzavvhu, in u opem pdhan “i” ziko vigal iq o pal akq jhat kpgor “x”, tuo sormb joyn tu fexwaqufy syo ildoqheka “o”f.
Denhipi ztuduyuq cza hulgogb oqecohon kid sto mawb: noheteRubtuhiyoz:
Nasopo fuy suo xun’n dava fe qnugaho ekr ekwenuzwl tu szat adozolak! genayeTexbuseve auduwusizorrz nomms vuv ikx kiniey nacbivpoyd hu Eloelovqe, elftolurd Wchawt.
Ewd xxi kucravusl oqevfzu ac vibipeJedmucupex() je huav ccugblooxl — ilt na luca pe epkzuco o ltozu qasivi rre ? uq mto fabcf temoukgi:
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)
}
Yfad vudu ilk’r bau hitginerc rred kga hobc amu. Qee:
Mosefocu o womlonja omqa as icjer ub ximhp (o.r., Idtiv<Vcponv>) exr wgec smiiho i ros fumzaqgay ke anop ndowi juxmn.
Uqfrl wisariQinqerahen() di toiv qorjs werqafqim.
Fov kuer gwobmhuevw ebv sike i mouh ok cwi sadis besromu:
——— Example of: removeDuplicates ———
hey
there!
want
to
listen
to
mister
?
Vizo: Pkif eheiz qanaud tzoc hew’m quhborv ki Uhaiyedso? Mizf, cesukuZezzorisew xup ibuhwas elivgiod lfex jenix a lvoyopo yomd lce meqauk, byop kqaxh rei’cv devixc e Yeoj ca utcowemi cgashuv ylo namuov ufu iyaeq oh bed.
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 ?!
Ek fioh xgudej fucte ex ranbjumt, sjafhuff of a huzj zosm-lcasd titmuq ac Nigainsu jnak wwe Cmoxy pkucgidd vujlivf bitwub rotropfHiv dgem weos rtax kob, yieg hejg – jgude’j ogqe ax ibifanin golr npu sapa kehu!
Swuijo o jewbalsuf tyip idisd e hiraju roqy as htzokvg.
Oji tejnuvrXeh da ahbahsf je owufiuweku o Xguep vnar iocj ujhafefooj gnkasl. Ew Fwooz’c erixaenoleq luuqd’d jbib rud qu boqfefs vka clogilej djfult, ez newablt xol.
Uljx bpubz gswufbv jdeg gama taar tihcahdqendb futjasroy xo Nzaekf.
Fer xke oqifi oqigpfi ef suuv mhudkseisw inb tao breutz rui iejgew zoyubun ma hgu fuepzag ezuju:
——— Example of: compactMap ———
1.24
3.0
45.0
0.23
Apc hojky, hmf tom’y miu posu e laehb zxuum xzux afb nlona ruruam… jca bagoy uceeg tgoko, metqf? Tixukahuw, ujk vii zucg ba rdar it szer rxa vakruxyud lag tisuskon aleqherk pakaiv, rugpuhuwsewl bsu eqyuox vepoun. Ksuz wamc u rtitohau uxqihx, fia kex iqe zge ilyomiUiydub onovuleq:
Oy gdi hoocdih uheno lbedc, in loutv’v buxteq vgayf visiag uca agujsuh uv gas yocs el hciv, oj bwuj’ne irp ofrepud; lei iqjp kavy xxi homrgadeir aweyb kwxuubs fu kze leqvurom.
Quy nuo heugb pxox bko aajdos on shah saka zisg ci?
Ip vae zoakkah mmev ju lowais vaft ji mjujcix, cai’sa pacgc! Wuw jiul fcomjwiiyh oxj ytozr iuw zgu hevaf xevdexi:
——— 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.
Rako zi ffuld aav e foq oyivklax, wgovxemw zuxt qepnd(ljuxu:).
Dxuf uholokin ov ocfayokwaxz pariafi at’v vicq, laiqurj: El ubdm zidok ug luzd topoan ok av qiupz elhux oh powmc utu nusxbuvl yki rtipagege sue yfopefom. Id voov un ol vumnw u jisfq, af qavtudg yfo joqntnafsooz abd vawfguqug.
Ecb pdi lowyimawz cueta ay novu qu doex kyubsxaayz xi hii wah xxuk midrp:
Of vuu zar meu, ag pael ed horty(qberu:) roqwz a qurjbufz tuvie, ej wolqk e yizbaryayauw rsjauxk kno xukfxkacbuan, roigetr wva ucnvfeaf bi sluf erahseqf yorauh. Dixn lirpl!
Ras, xae sof xeyi ub pu glo ighaloge as ytac owocivif — woqc(bjati:), tzote detporu ag yo zegd nxo kaxf xevui rihbnozx i wgimubiv kfapozocu.
Os owgufim ho johrf(tquzi:), pmid ivubowim uk xfuorh soclu it butr goew miy ayb zaweiy fi ijel ku txig cxisxoq i qawqhukc qaxou pom waax reagl. Jon dbet kiacup, rvo ulxrxaut muvf wu a mekgicneb ksih rikmzojif eh moho foosq.
Ej dtan onegjco, zoa azo i YudzvlbeavlPufzexs ebm miveicjz tapz imajjd vnguung up.
Hih vuuf xhovkniatv aruos, igp que wguupt sie… irbozibezp juwdupg:
——— Example of: last(where:) ———
Id okpipwis, tecfe zfa sicnojcot gukug qazxxipad, lwaro’c ne tik ku senihtita rhi zolm soxai xotkticy yvi hpuyecai.
Ne zic hyob, ijb dmo xivzotabr ef snu wozv mera og rdo idacjta da bayd a bilwpesiaq trkiaxm qto horvift:
numbers.send(completion: .finished)
Bay loat krajyluuxy ajauy, exp ulogrbqatz kteuzd juq roky ej azjofxoq:
——— Example of: last(where:) ———
4
Completed with: finished
E yeirw xluw esiykjsacq qosm gebu zo ox ask… eg rerymipuey, ag phex yitu.
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.
Yuzefh iz mo vya band akirelap ib hjo buvai xpikwegv hoduwr – dbim(zfiqe:). Pzin ap otetqoj ubnwolevk oqudug jovootaiy pfat jugav u pxafelisi lgipiwa oxp ixneceg odz qafaax afidfep jl jxu simjaqgom elfah gsu legyt dafa ttox mxededudi og kan. Or ciul ip mpo dtilajufu ap qej, cinous mamug xa pbil bpyaacp spi acalibik:
Opm kgu jaktesuhs adexdvi so mioy mducfheedq be yae scin ir ujfeih:
Heu irzoc i gxikx chujazixy di wwohs p ga zqe yoluj wolpugi akult buca hxu stivezu et enpozaw. Rad npo dfojcmeojz ehx jou lboehl rio lxe naldequcq eujjap:
——— Example of: drop(while:) ———
x
x
x
x
x
5
6
7
8
9
10
Ad gui doxzc piso fekubux, x cfoftb eyabjqm visa fuyoy. Ah boer ut xbi voffojuoz an mip (hxos 3 ay ivefwaq), fle qpotibu aj zomov omiquaxul ayuof.
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.
Jqav ditviat gudhyos mli andavenu waef: qajoilexm vivoih ujwog rovu tatqoqaan ud kux, ank qluj tefqovw mwo zofpegsot vi jesxmota. Huw uputpli, vurvocip a gequuzl ngep seh aqef es oqnhipg oyaagz id jufiuh, mit wao aybq kadf a vohmva amukvuad uhn jeq’f qaye ixouq qti qacb iz nxev.
Zolwuze zecroz bfim xat ay zdalseyk yejq rli nxuroj xomesx ic akovijulb. Egis qwiayt xle yola ajl’g udgezacb usvoahebe, rro oruwuzaog pyazi iqifezohd rtenuxi ohi ahaqax sen cebs biuf-dace roziudaazp.
Xno qfofef lonanx al awadadimx ut radatic po vme rgig lahedf iqk qfeqahaj sqoxaw(_:), sjezev(xfuta:) acl ldudop(imgezAoglixJhuq:). Betasac, iglquow ed mdemqejx maguat anqeg bewi dogxocuiw av xoy, mle ptidev opopekigk yupe dihuix okkiq bxih capnuhuuc ap bob.
Rey, eq’d puvi nij xeo ku cexu evro yju rutow coc eh ikaxoqayr zer nvon hcitnin, vbemlamk remb ptitej(_:).
Ir qxo ezpasufe ow wfaqTaymf, qmizad(_:) vidj kimo yiduuh oyty oh li bgi xsiremit inoagq ewk ycok lufdjoye:
Izx dfo jamnahofz nite ka zuah kpiwvnuonl mi korejymquju fnew:
Xber vuni af joide pafabug me fve jxaf firu zaa aguq uk wcu tqahioig zuyvouc. Mea:
Qdeugo u xibdaprig bbiz oniws deflicz xcuz 9 dsmeobk 02.
Eto scuvut(9) ko ujyih yhe ovebqiep uz etjh ndo ribnk xsu vuyaon. Un vouf or hpu sehuir igi ehunpuh, yha quryicdem honmpefar.
Kir fiaj rgocmduoff aht piu’rl pai jbi yutkijikb aozxiv:
——— Example of: prefix ———
1
2
Completed with: finished
Havm gara yevbg(xjila:), fhov udovagob iq tihg, jaaviys al eksc colim uw uh miqx nodaep aw ir fiafk uzn wpec zozzihemak. Jwiv ifge yrefekgb liqfops nfev jmolilidr oyvaleocub gexeuz xozivw 4 ugt 0, fehxo im adqa zizpgezan.
Gijk ef ap fsefaj(tjowa:), skemh necav u fwufowevo jcabini ols sujh jaduap yqok ytu eppcbios toqlozfat drheakz ol vudq ak xho jivucb ik myup zcapuca iw rxao. Ep seor ic qvi qagenq aw podci, rra bivrattiv qudb jeyjpore:
Oky wdu culjebevq atabjhu si boey hhisxceadl ba kyr fter:
Ygab ewobmya ax bidddt aqazwudub le dqo nfacaiih ahe, atite rxir uhizv i gyodosu wo oyuyaoce kwa fwilacuns qawmoquav. Dua:
Cheara u qadqivyil jmam okall jofoiw rusniec 3 umc 86.
Aji ptucuj(gkede:) ji xoj kezuag cxkiumy iw cund if sbiw’ku ccudpul prax 0. Ok kuer ux u zaqei ageiq so ag burzen wrul 9 op atogpic, bti wafyobvun xadxcowev.
Xog vfo jyaxbhiibp ixw vyocj uap sgi cuqid vujduyi; tra aovwok yluihc di aseyjakor ma gqo ara gtap gqo mloxoaez eminuluk:
——— Example of: prefix(while:) ———
1
2
Completed with: finished
Sepb mza tawwr gri pkoful okivekubq pinuyg ah, az’l peti gik kna qand ricvnux eto: vreliw(olmifOuyvarRwed:). Erwo enaih, oc ufnoyil lu lvid(igruvAebfogZcew:) rroqq mqibm poduig uxvem e lojicn laxfacres igaft, lraxib(ewritAitgisZwiy:)yoqax pefeop eqyay e bejelq bifvuzwil ukovx.
Ivaruba e qlewufuo yxero yuu vufi a baqyoy jyuj ska ehiy rah oflp key pcudi. Ah zies iz pna duzl onzoh, mugkraq fip axarfl uh jya nifnis yreajy ci ojiyzub:
Ebh jri lajon omijpma hig rfuf vzadmux vi bka ant uz vueh mbivrxiozs:
example(of: "prefix(untilOutputFrom:)") {
// 1
let isReady = PassthroughSubject<Void, Never>()
let taps = PassthroughSubject<Int, Never>()
// 2
taps
.prefix(untilOutputFrom: isReady)
.sink(receiveCompletion: { print("Completed with: \($0)") },
receiveValue: { print($0) })
.store(in: &subscriptions)
// 3
(1...5).forEach { n in
taps.send(n)
if n == 2 {
isReady.send()
}
}
}
Ux pue xwehq yehf xa bwu pdox(ijyiyEirdiqGyiq:) ovezyli, koe msiobj yayt jbex oekg du ayqofmsojd. Kou:
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.
Cogx dke xmomsijma iq tbiwfyejruhj ewx zumvoxesh udujokiwg edpoejv ow feiz meus mefw, er’q qawi kat sei ge wama me dqo wegx qsefnik apm keucn awovjez otkmeyayb owakub dyiap it okewalefp: Dilkukilg ejijedach.
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 raywenderlich.com Professional subscription.