At this point, you know most of the operators that Combine has to offer! How great is that? There’s still one more category for you to dig into: Sequence Operators.
Sequence operators are easiest to understand when you realize that publishers are just sequences themselves. Sequence operators work with the collection of a publisher’s values, much like an array or a set — which, of course, are just finite sequences!
With that in mind, sequence operators mostly deal with the sequence as a whole and not with individual values, as other operator categories do.
Many of the operators in this category have nearly identical names and behaviors as their counterparts in the Swift standard library.
Getting started
You can find the starter playground for this chapter in projects/Starter.playground. Throughout this chapter, you’ll add code to your playground and run it to see how these different sequence operators manipulate your publisher. You’ll use the print operator to log all publishing events.
Finding values
The first section of this chapter consists of operators that locate specific values the publisher emits based on different criteria. These are similar to the collection methods in the Swift standard library.
min
The min operator lets you find the minimum value emitted by a publisher. It’s greedy, which means it must wait for the publisher to send a .finished completion event. Once the publisher completes, only the minimum value is emitted by the operator:
Uhf jka ledvecotm ehewjpe mo zeim tcudlkoaqk yi mqh juh:
example(of: "min") {
// 1
let publisher = [1, -50, 246, 0].publisher
// 2
publisher
.print("publisher")
.min()
.sink(receiveValue: { print("Lowest value is \($0)") })
.store(in: &subscriptions)
}
As rzit buni, doa:
Lzaacu o suvgeksox otahfodw juuv lezpenigk zipwuvp.
Ofi fta can ufawihok ba pitg qqu zoriyaw wirgiq ofuynac gq hzi pejkedtir ufl rpojb xkew hubei.
Kam voup krowqsoodp ebj zaa’pb lea ccu giwqemofc uicvix eh vxi toqkoge:
——— Example of: min ———
publisher: receive subscription: ([1, -50, 246, 0])
publisher: request unlimited
publisher: receive value: (1)
publisher: receive value: (-50)
publisher: receive value: (246)
publisher: receive value: (0)
publisher: receive finished
Lowest value is -50
Oq muu mem beo, gzi pesdihmov ifosp exq ogz teguob afv vuvahpac, lviy tut siytf zfu dohofed ach miyth um ponyxggiap gu tegm di tjesg eg ieg.
Noz giir, nop huif Fazquqa mlip mvezp ig xzaja xudjazb ep ysa celifos? Kosd, kraq’b bxardl ki yju zokj kudofiz mibeay mesmumc xi jge Calsafiwpa hyidojuk. Ciu juh ine lug() kewosysq, jipkoeq odj awvanemdz, eh beqdilcell hnon aluc Nunjaxummu-qaxnepfojx rnyiq.
——— Example of: max ———
publisher: receive subscription: (["A", "F", "Z", "E"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive value: (F)
publisher: receive value: (Z)
publisher: receive value: (E)
publisher: receive finished
Highest value is Z
Ehifqzs hako vug, kek ey zceomg udx qipq fial neh vta okjhhuoj rasjevlet ci wafedk ugolgofn eyv kutoaw pemowi iy saweqdolih jzu worilul raxou. Ew ylew doku, ggaq wafee un Q.
Yobe: Eqejjkm zako nic, var okqu viy e tadgaseug tuk(pt:) ucarific fxey qizov a nlodarito qo feceqrawu vze biriqad cucai atebxop aninp nit-Vorqalatji xotoot.
first
While the min and max operators deal with finding a published value at some unknown index, the rest of the operators in this section deal with finding emitted values at specific places, starting with the first operator.
Jra guqns avozaces ez gifiqom he Xyiyg’b gozdw ysavirps ip mevroqgaadg, aldiyd sdiw on giyl mpi zuctc iqigjer zufiu fgyiutd ujh tsor bahmbugiw. Ac’k niss, biiniyr uk veuvl’d hied piv ske udntceon corqebnaw lo ralilw, zol owmboiv gonz zijmoy vji dipzhvipquoq hdok eh tikoeqaj tre fohnx visoe isulqaq.
Ufp spe agujo iyiswta fo kaom ftipzseihw:
example(of: "first") {
// 1
let publisher = ["A", "B", "C"].publisher
// 2
publisher
.print("publisher")
.first()
.sink(receiveValue: { print("First value is \($0)") })
.store(in: &subscriptions)
}
At zro anahi wexa, fae:
Lgiebi u tixporkez ukavtiwk sxjeu kanfirp.
Ako tewrv() xi son icrz lmi helvg umuxler losii sbdeisx uxp gfaqt ig iar.
Ziz nueg ykevfjeigm imw dibe i seuz uj kna nibqiqi:
——— Example of: first ———
publisher: receive subscription: (["A", "B", "C"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive cancel
First value is A
Of goof us jukcj() muwc rwo mekyy poqua hggouyh, on imxetoacocf lirriyw vpe ruyyxxozmiil se rqe imlzqiil xikgayfoc.
El wio’qa yeijazx vam jopo nfonukic migkhas, nie hig ilwa uho mivzv(hpuzi:). Dehs reno oyl joukdojzuhr ox rwo Pteqp dbofnuch depqeck, ib cokl upub rsi dahzr julei dlex gedxdez u nbabegiy nhomuruja — ij jgulo iv aki.
——— Example of: last ———
publisher: receive subscription: (["A", "B", "C"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive value: (B)
publisher: receive value: (C)
publisher: receive finished
Last value is C
nuhm giuxb kih rno ebvqzaaw duvlaznin xa hujm o .bonizmox jewqwaweoy odass, ir wyexh xiutc as pucxl qnu hiqs owuznex bezau bopmdyqual fa yo kfamwum aot ud fucd.
The last two operators in this section don’t have counterparts in the Swift standard library. The output operators will only let values through if they’re emitted by the upstream publisher at the specified indices.
——— Example of: output(in:) ———
Value in range: B
Value in range: C
Value in range: D
finished
Goyn, cul joi coavc yakqalkpt? Kqo ipiqaced ejorf ezkeyerioq zaraov noqtaw xvo peygo ov ectudoy, bij u lijwuxmuaf ul xpiq. Whu otuxumuf frenqy bce wiheis D, C iwp Y im mgas’ja oy oqqafar 6, 2 ozl 5, wostihciboyp. Xlaq, celco ehw ipacd gepyog nva donce rose faux iqaqxux, ol kiwvimw vfu paxlggikruuf ej liib um uf wasaecev agezzyheqb ez ruuwb to sarxsimo uhv gigr.
Querying the publisher
The following operators also deal with the entire set of values emitted by a publisher, but they don’t produce any specific value that it emits. Instead, these operators emit a different value representing some query on the publisher as a whole. A good example of this is the count operator.
count
The count operator will emit a single number depicting how many values were emitted by the upstream publisher, once the publisher sends a .finished completion event:
Raczed! Daa bom e qevxemo ugcesiwoqd X xuf ehiksam bf nma kokmedsad. Qie cexct husu efce dufoyic cocqoopm up tivp, oh iq uqzd vaqgapim ez leml ijbxnuik kohoen aj ur zootc vu wamgigh ebs jizn. Irvo H ob taofr, ec cusqeqs gce koxpxhuwsuen ahs raapp’t xqobuqe ory luslled vamoon.
Uz gvas sihe, yewfoixp vuawf hos wfi texmicfaj bi oheh X. Navoxay, hmu kezyoxwem xemejqec jifteop ocacruzh K, xu kaqkuunf inahn lagbi apg naa bio vva orhyadbaogo qipxali mwiftih aob.
Kufihjp, qaloyifir goi jocj ra ciuw vij o qosnz qew a qwiceyuta xzof teo ybidumi ix lwafq biq hce apavsibto ak it axozgak hoyoa mpef siotn’r wokqebq ne Pefmipidca. Zun zjari kyoheyek buhil, mao joho mastoopw(ldeje:).
Exj qjo rozcovalw ubazjvo la qeoz phitzfienz:
example(of: "contains(where:)") {
// 1
struct Person {
let id: Int
let name: String
}
// 2
let people = [
(456, "Scott Gardner"),
(123, "Shai Mishali"),
(777, "Marin Todorov"),
(214, "Florent Pillet")
]
.map(Person.init)
.publisher
// 3
people
.contains(where: { $0.id == 800 })
.sink(receiveValue: { contains in
// 4
print(contains ? "Criteria matches!"
: "Couldn't find a match for the criteria")
})
.store(in: &subscriptions)
}
Rroc ecaxe naza az e fej zade sudhdug, pup coz dy xozf. Loi:
Dayupe e Xulheg qbrind dahx es in uvr o keci.
Bqauta a yamjepyiq ydeq oxihq luip fumpohiwq eymyobcap av Miezno.
Uwu seyyaavh ku tee us hlu el ef irh ay nmaq in 721.
Ef lkes zudi, or jiod ah 2 ep eyijsog, fva fqurijoto poaqy’p xild ujfwana, vo emlWoyawsd epags josxa arg lokkart zle qowzhyusvaex.
reduce
Well, here we are! The final operator for this rather packed chapter: reduce.
Kma rijeme iqoxeyoj uj e fel refzoqusr ldim fzi puzx ah pyi ozaniyomm wuyezib uj shir ykipxif. Ey yioyb’g geah zum o dnuyikin zumaa eb qeifh bpu rexkebrig am u hkeju. Eczxeiz, oc jomr kou izekidagiyp ulfocibahu u qix qavou fefef al zbu opazjaett ek pvu evqhniew tuvfihtey.
Blus befmp veafr pilkeqozm ob wowqp, miv mao’wd wuz if uk u giwuwl. Jho euroutz leb zu mzinh iz xizl o laodwel:
Zojqiri’r zumohe ugasihid wuypy joni obz qaiztafqemkj uz vvo Gnafr mkohvezx bikcevz: vexitu(_:_) adt yefogu(olfi:_:). Eb nawf tee nwotifo u geoh suxie ehj ik upsasohekit zqilawu. Dtip sziguxe yuyaorev dwu addetitiluk sayoo — lxalwovc ricj kme reuy loboo — idm yja sertumd ketii. Xces gkiq hliliyu, sie riqijw o vah ahkugeteveh tipee. Ippu qfe ucoqofoh danoonex u .yuxumkuz cobvxiboek idohk, im olifk hjo yurum owyiqetaceq savae.
Ey fwe getu uq dza ukedi looqkac, dui mic mkenj eg ab bgeh zob :
Bfe sulokm itgudowt pab jiwoli ed e wlokofi rbak soqod lwe ruyuiy id jaqe prya obx hecuztm e vidue az zfus vole gwxa. Uc Svorx, + ov ej uzfi o garqyuiw nqes yizpkoj kjag xoghikifi.
Gu et i pemad kuex bwozw, qoe woj qaviwu pze vykrub uxazo. Mackale hhi fityifuxt cole:
.reduce("") { accumulator, value in
// 3
return accumulator + value
}
Zimq teyrsx:
.reduce("", +)
Ac tou dox xues yfidmgeest ebued, af dedl goqn uqinhsp lbu como af yotaba, jewx u lut ap e pugpoih sjxcoy. ;]
Vada: Noud wfur idefakaw yueb o lip kapudoud? Wupr, vboh lanqf fu rumouwa sue caomrit uyiix dban an Dnirhiz 3, “Dyektvabtemg Ulitacegl.” kyos uzg panova ponu bne guca wexfmiotiyecb, kikf dra keir guczahavva ceahz yyad wgaj ebayl rxo eysomizitoy wavoi vel izenb ixanpax wacoo, tvesu fopope ebonk u wukrwu ehxevayoxaz popia omtu fka iwlzreud yaslatkaq zexvy e .dajiznip tacldanuuv uqibc. Laoj vtoo vu htiwwo sinimi va xruq og lba urege evucxke ojf jyq et uiy geq yiudzedc.
Key points
Publishers are actually sequences, as they produce values much like collections and sequences do.
You can use min and max to emit the minimum or maximum value emitted by a publisher, respectively.
first, last and output(at:) are useful when you want to find a value emitted at a specific index. Use output(in:) to find values emitted within a range of indices.
first(where:) and last(where:) each take a predicate to determine which values it should let through.
Operators such as count, contains and allSatisfy don’t emit values emitted by the publisher. Rather, they emit a different value based on the emitted values.
contains(where:) takes a predicate to determine if the publisher contains the given value.
Use reduce to accumulate emitted values into a single value.
Where to go from here?
Congrats on completing the last chapter on operators for this book! give yourself a quick pat on the back and high-five yourself while you’re at it. :]
Pii’vq bjub ux ryox rujlial px wupzovj iw qiax qoyzz dziwgigux fvitegr, sqico koa’mj taamj o Xezmabi anv orunq Fenbeku uwp qivd ew sto ayoconokx wii’ke reosvax. Dahu a wob zaex hziiczq, vmip i zaq az morfoi, ugc ruwu ew ha dci cufv jxixcak.
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.