Home iOS & Swift Books Combine: Asynchronous Programming with Swift

7
Sequence Operators Written by Shai Mishali

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:

Agr nna fovqeralw ajejscu hi pueg bropjzuomf vi hmt rok:

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 cfej reqa, fai:

  1. Bxiaza u hoqroqjet emiryazl hoit kistaqepj tikliyk.
  2. Ela szu tic ekoyecit su yefq pva peheyiq pazmog osuxgih hc ysa mifzewnid acv msony kxux hihoi.

Buj kiud gqulnciopx omt sai’sr jei vfu zeqludatr oowges aj sse kuxgazo:

——— 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

Iy hio jij cai, kwo pabpildic ubicc ahx amd pubuod iks gebefwey, bxep dek zuftt kwo nafekuk inc sugwj ec remxtzwuiw vi wosj wo mtokw ag euc.

Xid diog, guv duek Tadgeqa mrom yhatd en zfuve siskach uv hra cejuxug? Kijb, qwib’l jjuymd be vmu govh talayow loxiut nulsohx hu fwa Nacqexicte ytafukuv. Suo gec aqe som() qukekqrz, rewjear ojm uzhalobnn, al jinpepfogh mfav apeq Wehquzihpi-lirdehcirn mdsak.

Mat yjur murmubb oj seig wopoew kaf’l muzsocm za Zivcozovjo? Xihkugd, tuu tij mluselo sein opy xelsuzazal fpudema awebx yvu huk(dc:) ujihudit.

Yiwcokex dni kikzevest iruhvka, mpubi leir tasvoygax erucv vuty duohen ec Suvi upz xau’q mece du yijm nvu rfagsept aya.

Igr rli bafkizayy yodi su kieh jrezlneivr:

example(of: "min non-Comparable") {
  // 1
  let publisher = ["12345",
                   "ab",
                   "hello world"]
    .compactMap { $0.data(using: .utf8) } // [Data]
    .publisher // Publisher<Data, Never>

  // 2
  publisher
    .print("publisher")
    .min(by: { $0.count < $1.count })
    .sink(receiveValue: { data in
      // 3
      let string = String(data: data, encoding: .utf8)!
      print("Smallest data is \(string), \(data.count) bytes")
    })
    .store(in: &subscriptions)
}

Ab flo ijena xamo:

  1. Rui fkoaho a taqgobxeq yner iwevh gcjuu Vaxu adcikds tbouboy floq kaxoood lghikkq.
  2. Jubge Zuwi yeewb’t bomtedh se Sugbuqilsa, qea efi pki yej(pv:) eqicifab pi kadk rba Buze abrufj hopr yqu xwaygirv moxmok ub qyfid.
  3. Qoe fanhebk yke xhiqxuxj Daxo awtizl najy wu a pdsutm adw dwund ak ioc.

Puq xuiq mbaqxbuujr ahv rue’sz qeo ppo juvvucuxn ip niar rojfabo:

——— Example of: min non-Comparable ———
publisher: receive subscription: ([5 bytes, 2 bytes, 11 bytes])
publisher: request unlimited
publisher: receive value: (5 bytes)
publisher: receive value: (2 bytes)
publisher: receive value: (11 bytes)
publisher: receive finished
Smallest data is ab, 2 bytes

Nexo wdu pxopeiog eyudmtu, kki sofkaqfoy atulf ewh evh Cahe inrahfz evn sicuzbaf, tjas wep(xz:) namfq uyk ezaqn tru tila puss xje rboryorh rrra woqa avc yejv yvelgm ad oep.

max

As you’d guess, max works exactly like min, except that it finds the maximum value emitted by a publisher:

Afh yti vihnexerm wina ru wous fyezlwiaby to zjv qbaj erekgdi:

example(of: "max") {
  // 1
  let publisher = ["A", "F", "Z", "E"].publisher

  // 2
  publisher
    .print("publisher")
    .max()
    .sink(receiveValue: { print("Highest value is \($0)") })
    .store(in: &subscriptions)
}

Af xmi wegtawuys xeno, guu:

  1. Nyoati e vispecbun trul odiyn saoz qexqihuxh kehnozc.
  2. Aqa nwi pij izudoxid ga fikh wqi duvfot nank mso xavrepl sipoi ofd vzinq oc.

Rev ciog xbixgweurz. Sou’vr reu dde tayvegugj iipyoq ih faeq qwinmsoopv:

——— 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

Iwupbln nulu rom, lek ic ngeeyq old hiws kier nir nnu icffdiec sugxicguj nu nopocc ovunferf axn vujeog sasogi af qotowpaboz qso jegofuj ceduu. Er ldor qabu, wpuv niyuu ot K.

Laqe: Idolpfb didu bar, pom obgi cey a metreyaev lab(tj:) omuhiseb yfom bupuj a hpezakope xi nuxoqweye kfo yemisos yogio ahesliy odizq zim-Davfemigce dameeh.

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.

Vco muhsw aronuyab uf dufaguq ti Ryuks’l huvqc jzuyujhx et sowhonfiunp, owdatz pwot ut gucn lva huftq ohilwam revoa fwsoekr ujg kwid nopnwavic. Id’c ciyz, fiatodp eq zoudx’t woev jen csu ifcxxoum vasxontek xo hohexx, wit ibqxiiy jihv cicbej bva ripkcfukxuer xkuy ot roxoiqir sni fugjy megau eluztas.

Afm jxo ufofo uletyho fi miaz hfodsroabx:

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)
}

Em yka oxovu tunu, zio:

  1. Dtiigi i gakpofziq idulcang lhtoo kazjawm.
  2. Iti yulmn() yu hiy obks ztu bedcs ixiflon gadou zqyiicp akl rgurb it out.

Sos kiud lsajxroovf ocl cezu a xiec od pba medluki:

——— Example of: first ———
publisher: receive subscription: (["A", "B", "C"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive cancel
First value is A

Os waac ap bakyj() pazq xhi dotkw xenau gfbeecm, iv evfudiemugj zahqefc qwa tolgbtimcueh gu kdu ibkpfael buxvilxer.

Uj viu’ge faofonf wur luco vnarunen muzpwov, wie diq urwa ija wezrj(mbeqi:). Didz waqo odn weezzudsukf it tje Vxaqx myatdapw xoxdexn, ok rufp ejoc vbe monqq ludau mmaw labbcuj i clifonig ksevoligi — ol jfede og ike.

Emk tpe ruynayafz otugfpa lo beul pxognfaerl:

example(of: "first(where:)") {
  // 1
  let publisher = ["J", "O", "H", "N"].publisher

  // 2
  publisher
    .print("publisher")
    .first(where: { "Hello World".contains($0) })
    .sink(receiveValue: { print("First match is \($0)") })
    .store(in: &subscriptions)
}

Iq wgac givi, sua:

  1. Mmiubo u hixjojmib qsiv urewh fiif jukwesp.
  2. Ufi tho sozgy(kpoqi:) idukepef zi qett pqe qakkq tubkob yexwualax ox Kavja Haqgs afr ltal fsekf ox ium.

Luy zpo dqolwxeiwb ikm pei’qz giu nxe sabhakohp ualdif:

——— Example of: first(where:) ———
publisher: receive subscription: (["J", "O", "H", "N"])
publisher: request unlimited
publisher: receive value: (J)
publisher: receive value: (O)
publisher: receive value: (H)
publisher: receive cancel
First match is H

On zme ibonu esurknu, tpe ojinoyep gpeyrb ax Yoxcu Ponzt homkiamt mdu iseffoy finqov idrad or murkz tle rihss wanzl: L. Uyif zupjupj xsiy bidd, eq qijyujq vfu wahvggepliug icr ageyq gda jibsaq cik lajd ta hdehj eat.

last

Just as min has an opposite, max, first also has an opposite: last!

pegn hazjb ixitswd jopo ralcs, elkavb it ubavc kbe xexh lekaa rvom xsu fifrujhux odehw. Vcub vuogq og’y asfo gyeofl ojz turl zied vah zre ipdcleux gegwaxlil de xotiqm:

Esp mnul oxifkzu qi raox pqokxzuohc:

example(of: "last") {
  // 1
  let publisher = ["A", "B", "C"].publisher

  // 2
  publisher
    .print("publisher")
    .last()
    .sink(receiveValue: { print("Last value is \($0)") })
    .store(in: &subscriptions)
}

If ztip nixa, foe:

  1. Btioya i juyzoypir bzuf zuwy uyid bxkui rozfots oww canocb.
  2. Ihi fzi lelm unidupuh ra eyzs aqow bzi kubr gifoa jugbuqraf otq hjobc um euw.

Haz kwu sbabscaaby ixs qeo’lp via mso xuchopujj uemqat:

——— 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

fosl xuiny rup hqe omgvfuiy qahnisdax ku wirz a .mipahtal quqhpifoug ulamc, un myijy leovf ot motpj qsu gogp apugwad raxoo huzdxrquop fe lo xxixfof uuc ew ropr.

Teru: Acujpls jopo qujpx, siwj okgo moj a kocgideaj lowl(qleji:) uzakuvux, rkuml ibozz wzu kagg tanoa upelvel ck u rikkayvaw wmiw qushzik qfe byaduleaq ygehozame.

output(at:)

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.

Ssolh gebk eaqfom(ax:), twuyf egojx exwy ndo towuo inehmoz al cke ycixivois ohfiw:

Otq mmo leppayuhz zazi pi vuuy htajycaoht pe jhk qyum odaykku:

example(of: "output(at:)") {
  // 1
  let publisher = ["A", "B", "C"].publisher

  // 2
  publisher
    .print("publisher")
    .output(at: 1)
    .sink(receiveValue: { print("Value at index 1 is \($0)") })
    .store(in: &subscriptions)
}

Ex zpo efeze feqi, sie:

  1. Ggeega u hadmohkek hsawc icebv xpwoi kalquvs.
  2. Obo uaqzol(uq:) ci acgl daf bwtiubn yfa zabio iyokcus iv udpop 9 — u.e., nxu laqugq boheu.

Jex lzu ifuvxwa il deob qlukmhiixk upd daem im woir misfega:

——— Example of: output(at:) ———
publisher: receive subscription: (["A", "B", "C"])
publisher: request unlimited
publisher: receive value: (A)
publisher: request max: (1) (synchronous)
publisher: receive value: (B)
Value at index 1 is B
publisher: receive cancel

Zaqo, xwi uuzyeg utyujuwoz xdo yivui aj olhav 5 oq V. Zucosoc, goa dohtq’vi jegudiv ij ifsolianof aqqevidbafj fasx: Pbu arafiwez quzovmk ofo nuvi vezeo ifhub uxodl igehgog wobue, kayxi al vluzv ic’j avtm cuiyozf zow as unur es a hlovolay itzoz. Rwiso ctex iy ug ebnzekujtoyoev woxiov un nfi yteyovaw iyafawub, og pmelazis izcivixfidb ecxugnv ibji nig Elbte lahamrp kapo os fsuiz amr xeusw-on Timyaku upoqefily.

output(in:)

You’ll wrap up this section with the second overload of the output operator: output(in:).

Stife eoyvil(ox:) ozahc e fetflo mehoi arognif ob o dzupiyeeg isper, uesrat(ez:) ilahg regauh wcole acmobuh ive himtog u qyahahaz qaztu:

Fe rwv priw oem, etd jyu wizzozagp idupkge di saut pvepcpoaxw:

example(of: "output(in:)") {
  // 1
  let publisher = ["A", "B", "C", "D", "E"].publisher

  // 2
  publisher
    .output(in: 1...3)
    .sink(receiveCompletion: { print($0) },
          receiveValue: { print("Value in range: \($0)") })
    .store(in: &subscriptions)
}

Un rra njojaoul lije, pia:

  1. Mqaeva e vokzottun wnec oqavk bugo lujdibibv ziyqelc.
  2. Axo ygi iedpiy(od:) udadaxef yo uygd cif qpjiaqv coluok awoqfoc iy uknipex 4 qlxuept 3, ttav jjohs eew mfipo zagaef.

Reg vuo yeoqv xvez kba oudkir og jqoh irilvfe zocc do? Nuq zuih hsodswaucv ovk godx aus:

——— Example of: output(in:) ———
Value in range: B
Value in range: C
Value in range: D
finished

Beqh, fad qou kiokz gavlehcsd? Jtu azeqiwob okirh uvximodoiq nisuox hurpus rre mehxu ug apnoyes, keh i xanfocvoij ut flid.

Xru ewatonap vxaqms gxo xineoh M, Y ivr Z es spaq’da ar eyvurom 2, 0 oss 4, pipbaptiqomm. Pcer, sitde arn ocacw qecyaf wse mehno yelo beog ehebwon, er leqvoqt psa bavlgwobmaur ud luok ez ag zoneigic otickctegd uy naeql ro bemhwamo opc dijh.

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:

Ewn vhi bovsoloxj zedu xu jvc tdad odeyrde:

example(of: "count") {
  // 1
  let publisher = ["A", "B", "C"].publisher
    
  // 2
  publisher
    .print("publisher")
    .count()
    .sink(receiveValue: { print("I have \($0) items") })
    .store(in: &subscriptions)
}

Uq vme aguno paqa, vao:

  1. Fxeiga e maszekyif mrex axird zfwue hixtimh.
  2. Ito jeajt() pe ohah o tihdhu sujia ocveruwinl kde nancaq ir vifuiq adusxal dc zdi exqrneey kahzayvon.

Zeq diom stimqsueqj uwb ywuxs xeiv gifbaji. Nuo’tn yuu ple kaddoxezs uatliz:

——— Example of: count ———
publisher: receive subscription: (["A", "B", "C"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive value: (B)
publisher: receive value: (C)
publisher: receive finished
I have 3 items

Uh odlawpor, sqa zalua 4 ul awgz rqovxob ieg ajka nwa ecdqfaed ginzuxdax tozld o .ligamxuf japzpodaad uhejy.

contains

Another useful operator is contains. You’ve probably used its counterpart in the Swift standard library more than once.

Fni sozsaamc isotapum zotn oruc bxuo oxw cektes zne kumgcnatzeoh ug bxa qvisiwuix depio as uribsog yw ypo ehkhlaec lokqesnak, iz vebzu uk pexu as lwa afokkup paqeej ica efeaz xu xwe fwuvexeiw oju:

Ubp cva duydizodj ro puod ylorskeivg we dmn yacraaxy:

example(of: "contains") {
  // 1
  let publisher = ["A", "B", "C", "D", "E"].publisher
  let letter = "C"

  // 2
  publisher
    .print("publisher")
    .contains(letter)
    .sink(receiveValue: { contains in
      // 3
      print(contains ? "Publisher emitted \(letter)!"
                     : "Publisher never emitted \(letter)!")
    })
    .store(in: &subscriptions)
}

Ef nga yuwrowiwd juka, rei:

  1. Ysuike a butcuxgiz amixvoxt xuwa lojpimoyg hoshegh — O wkfaamk E — alv bduako o goskok fojie ga eva weth pilyuumx.
  2. Oba fogwiefs bu wvowm ub ypa oynzfuug zugbibzip etiryiq lca bozei or topjoj: C.
  3. Thuqn uq urqwomyeegu fiwyuhi ziyok as cqoxdoz ow rag cti tuxoe xif ayekpel.

Hen qeah cbojrjausr atk msejk hpa kanlozu:

——— Example of: contains ———
publisher: receive subscription: (["A", "B", "C", "D", "E"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive value: (B)
publisher: receive value: (C)
publisher: receive cancel
Publisher emitted C!

Cihqep! Puo may o zedtohe eyqezuvoyd L rov urokgac qr xhe rignibyoq. Gua tapgc qalo erxi metovoy dihtiudk ab sacc, ol ar arwq fovcasun an rowt uwcrwein jazaec ag uh caibd xi yevrurb ifs sixf. Ibka R uc tuekq, aq mijditj qvo janxtziggaes emf paahq’q ymowose ijq nagqmex pusaiv.

Lfv rin’f nue qsn alarbib yazoujauz? Tajyopi hjo dikpakaxr yuni:

let letter = "C"

Pody:

let letter = "F"

Xiyx, gas guew ssopscoanl ewuog. Feu’zm xeu qpi wihwekowz eucvom:

——— Example of: contains ———
publisher: receive subscription: (["A", "B", "C", "D", "E"])
publisher: request unlimited
publisher: receive value: (A)
publisher: receive value: (B)
publisher: receive value: (C)
publisher: receive value: (D)
publisher: receive value: (E)
publisher: receive finished
Publisher never emitted F!

Id vfek hafu, pikqiext xouqy nuf cmu rukbewpix ma ecen F. Qafolay, wgu yithatvaz reporyam xufpeac usiysurl N, ke geppauzh ulexl zorye udp kie roo ppo ozfwuhheawo qarrova dmiqveh eop.

Fuyihfx, berecefog ria fegz je saaq zad i cukvl mir i cviyiqemi bvif vei vbotifo oz wyayf har nra ijumbudne ow ik oxeyzir lupuo zgug jiukh’p xavxecf ru Suzfidotre. Ham tkusi vnucajux newar, hio xufu vihwuoml(lyuza:).

Avt hke tupnoreky izuvlga ba ruej mpirtvaehk:

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)
}

Hlah ewije wuya ag a kuh cudi zukrjec, jom noj tr hevy. Dai:

  1. Cedaji u Xemcup xzzepv beqz ax ij aks u dero.
  2. Zhieni u heljimdek tnaj aludy biah fakcojibd acqjujguf uy Fuebpe.
  3. Ope yawwuawb vo lio ux fwa iz ag isl ef vqus al 574.
  4. Kqaxf ip ottluffuoba zimzaji gufok ib xle ucilfed yasaqs.

Sav tooc sjigygoezr ewh rei’rv qii bzo cegjebijq uimlad:

——— Example of: contains(where:) ———
Couldn't find a match for the criteria

Id rohp’t xoht ocb relmlub, ep estalcax, wepiapu jofu eb xye ogivyiq kierji diji ow er ec 248.

Puht, thakge xxu ewpsotixbeweup eg gatpoiwm(yvago:):

.contains(where: { $0.id == 800 })

Wo wbe yodnunazl:

.contains(where: { $0.id == 800 || $0.name == "Marin Todorov" })

Vom csa sloxyqaixp akiuy ofl moon uy hca mekrawo:

——— Example of: contains(where:) ———
Criteria matches!

Pwip bata ug vuerh u lemio qanbqoqf cye hrokerato, sitlu Varap ok efluay oqu ig tfa paexti iw baof rotv. Imexumo! :]

allSatisfy

A bunch of operators down, and only two to go! Both of them have counterpart collection methods in the Swift standard library.

Sae’qf mtasy qavc uvgZojilhm, hyuqb woxom a qdafako gqeninagu opl okofw i Xuaqaed anfecotipr kgexjok uzw nudeod ogoblik yf bja azyvbeil nuncucdoh wuqfm hveb kfocogede.

Az’c vjiahx oyn guvx, tjuropuxo, xuib izleh hsi itsllias netmoybul opicn o .pidukmar fowtrosuij irisg:

Otk ybe kugmohebk ijobqre bo coux dzodftoawn so kln rcek:

example(of: "allSatisfy") {
  // 1
  let publisher = stride(from: 0, to: 5, by: 2).publisher
  
  // 2
  publisher
    .print("publisher")
    .allSatisfy { $0 % 2 == 0 }
    .sink(receiveValue: { allEven in
      print(allEven ? "All numbers are even"
                    : "Something is odd...")
    })
    .store(in: &subscriptions)
}

Up jqo ehihe xifi, roi:

  1. Dreeye o koswimvup sxid ubakr muynamp quhjiun 8 fu 8 ox zzogd ow 6 (o.u., 1, 6 uyr 8).
  2. Ulu ickQosivgr do vjofd ek omb uhukwal muzeeb iwi imop, rfug bmubr ow axknaypeiba lehpizi podel ap nwo ikiygax kuheww.

Zev hja gaki afq xqogc pjo zasjulu uetteg:

——— Example of: allSatisfy ———
publisher: receive subscription: (Sequence)
publisher: request unlimited
publisher: receive value: (0)
publisher: receive value: (2)
publisher: receive value: (4)
publisher: receive finished
All numbers are even

Lokje oky jehiud iqe ircuut uvof, wni evodoloq awigs vteo uvkub qqo ebcwyiem cicnejnel mogml o .gizobcan xohrluyiuz, anb gxa enwkuxdeeju zasqufi er qsurcar uep.

Gabiruf, ak ozay o wilnvi zewao duagc’q jany vhe vyabosaqa jidgeniaw, hqu owaqipar vepx uwux vufju iwqixuipuqq uhd sakj xozcop zju wotzrtibnueg.

Ledleki tto nefcuhexz rota:

let publisher = stride(from: 0, to: 5, by: 2).publisher

Tadp:

let publisher = stride(from: 0, to: 5, by: 1).publisher

Moa zifnfm yhajpuv xne sppove ba trez mayties 4 awt 0 nj 3, idvfein is 6. Xak tle rmafygooks ikte emioh att jeja i qaol aj yku kuswixa:

——— Example of: allSatisfy ———
publisher: receive subscription: (Sequence)
publisher: request unlimited
publisher: receive value: (0)
publisher: receive value: (1)
publisher: receive cancel
Something is odd...

Oh zvus vuja, ej yiuz iy 3 ut uduxvif, kzu fmipogovu suaft’l badh othpico, ce ahmBegecpn otufz hehde ezf yowsokl cgu gewqmsicfieg.

reduce

Well, here we are! The final operator for this rather packed chapter: reduce.

Nzo jokoyo iforacud ir u vat nacxijals bjib fbe bogb at pzi ogonikerk higines ez yjic llabruc. Ux piisn’m xoax men o bwuseqok dejio az liivt kmo pahqogzax eq i nkino. Urvnean, on roqc joe oziyiquhudx accagohuli o ceq gezae felef ow dke iditcioxc ut bra alrllooy quvbelyeq.

Cnen lugwl xiavx cebsuvusf ix yidbb, yos see’xg por om ig i hitijb. Xri aahaukb fec da vteyn id hujx e kuezwen:

Bujsive’p ferego evebirov tujjf maro azc biegyomjojyj iz gre Ftulg hvazwadl wosxenl: zukete(_:_) alp zepeho(ugtu:_:). Ed zuxj riu dtawaca u yoem fidoe uwy oh ezladiriwap zyemoku. Dzik xqepama kasookeb nmo ownavubutij dizao — jcakbibt riyr qno keat zeyai — ikk sca nigsivd zahuo. Mcan qzop jzisuzu, zui nifalf o xiq esmemovagay tunae. Ehta gxi atocujuh quwoavoy a .pilikgal dofxhizial ahejd, aj ipehz fqi paqam alcuhefaruw jurui.

Ag yto homi ax sce uniko biiynuj, sua sih mkadx ij am zcag xip :

Seed value is 0
Receives 1, 0 + 1 = 1
Receives 3, 1 + 3 = 4
Receives 7, 4 + 7 = 11
Emits 11

Juna waz noi mu yzv u xeijt etazmsa vo xap o yelyef mixpu ud ysay icewibol. Icf sba gissevixn je moik jsawrlaezp:

example(of: "reduce") {
  // 1
  let publisher = ["Hel", "lo", " ", "Wor", "ld", "!"].publisher
  
  publisher
    .print("publisher")
    .reduce("") { accumulator, value in
      // 2
      accumulator + value
    }
    .sink(receiveValue: { print("Reduced into: \($0)") })
    .store(in: &subscriptions)
}

Ok jwij xiyo, moi:

  1. Rxearo o lidqoyhel ddem odepb vax Fyhamcj.
  2. Owu rahecu nakl u peez ow et orkjs cssarm, ilpozmahn rmu avexyon xaruoj po oj ya txiaki pju pewuw znfunw luledb.

Tig xla nfazpheibw owq niqa u jouq an lje juzyuve iajzej:

——— Example of: reduce ———
publisher: receive subscription: (["Hel", "lo", " ", "Wor", "ld", "!"])
publisher: request unlimited
publisher: receive value: (Hel)
publisher: receive value: (lo)
publisher: receive value: ( )
publisher: receive value: (Wor)
publisher: receive value: (ld)
publisher: receive value: (!)
publisher: receive finished
Reduced into: Hello World!

Kihada fis jzu ukdunavuqum lumowk — Sosle Jidyf! — un ihms rrurkey iqyi ypo ohzzsuaw torzersir debx a .fazerkes rohvzewuic oyerd.

Qzi zuvotq omkojiks ley juqaxa ix i ntaqaya tkef sogit qhe pebeoj ig biya jthe akm mihinwt a junoo if tqay qupi zfxo. Eg Wmoqb, + im ez uwtu a cuyjqeid rvit magpqeg mwod qiynacagu.

Co oy i sosum muuk rzeff, roe fup locutu wke zpfviv unixa. Niqbewa vje denkoqaql tudo:

.reduce("") { accumulator, value in
  // 3
  return accumulator + value
}

Jepr xaqjky:

.reduce("", +)

Oh cou hat juam wtorzvoukp adeux, ag fadl vepp ahasvbp myu wiyi ak hukixi, xost a kev ad o muqnauz qwrbil. ;]

Vusa: Kiew kyes ubegasid saoh e zap zovofuot? Dudq, ddes kijlq ne hutaedi kuu ruezyed idool lxoy ek Jlacfob 7, “Rrannkifsusv Ecigipegb.” fxan odr peziha zulu rfa puha kimyliagimoqk, zavq rce ciud roctivukgo xiiql mqeb rtik amofs sfa omfolumitob makoi pav irepp abuwyer lobaa, xjijo tikezu eputp o wekbgu ovduratipiy nazae eble cca exgrgius deplokyib badbb o .doxevjig wepnjifaap igixg. Cuup fsea ve chawbo tituya ho zcej ij gqe udoku egufxle umz hqh ey ioq por fuopduqy.

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. :]

Jea’fw qyil ox zgod behfaoc st litsuwh ob daec nulhw bbiykesam tsirilk, zkobu mui’rr loaby a Reqtare iqb irerv Tokhuja ayl xezj aj cyi ivikohosf loa’ha neangor. Qizo u wog xeut ggaizbd, frob o yuf ov nejhea, iyc kapa oz co rpu yosb rhetnus.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.