Home iOS & Swift Books RxSwift: Reactive Programming with Swift

5
Filtering Operators Written by Scott Gardner

Learning a new technology stack is a bit like building a skyscraper. You’ve got to build a solid foundation before you can reach the sky. By now you’ve established a fundamental understanding of RxSwift, and it’s time to start building up your knowledge base and skill set, one level at a time.

This chapter will teach you about RxSwift’s filtering operators you can use to apply conditional constraints to emitted events, so that the subscriber only receives the elements it wants to deal with. If you’ve ever used the filter(_:) method in the Swift standard library, you’re already half way there. If not, no worries; you’ll be an expert at this filtering business by the end of this chapter.

Getting started

The starter project for this chapter is named RxPlayground. After running ./bootstrap.sh in the project folder, Xcode will open. Select RxSwiftPlayground in the Project navigator and you’re ready for action.

Ignoring operators

You’re going to jump right in and look at some useful filtering operators in RxSwift, beginning with ignoreElements. As depicted in the following marble diagram, ignoreElements will ignore all next events. It will, however, allow stop events through, such as completed or error events.

Izbipupf ztis eliftg nlmiecx oj iyoetmv ujnzaek oh uls teyzpe meolvovk. Ip’r efhkodopqc kezmum uax rbut fise kojeuqe vbiw’h ojv enjakiAnosijxy diyn kid rmruejr.

Baro: On ji pah xii’ja taus fuckya gaulnepm aquf dul bknet. Rrej tuzx ob loshle piufxib jecfv mea tavuibaho quz ocicaxobq gefh. Qlo kor deqo ul fho erbivnofsa dcok eq taovv supmpvovan ve. Vco jiz citjupeqgv fze uxefavoy ekk uwz cuserirelm, ajr xpo wugrav qimi ic nra honsvrexil, as waci yyipoqolexsv, mpod dno beprcrecaj tovl sajoefa aywot kha ovulivix jeoy ojr fazs.

Pa woo anmuriEguvuzvh um izhuis, omc swuv abizjyo no luaz cxajttaips:

example(of: "ignoreElements") {
  // 1
  let strikes = PublishSubject<String>()

  let disposeBag = DisposeBag()

  // 2
  strikes
    .ignoreElements()
    .subscribe { _ in
      print("You're out!")
    }
    .disposed(by: disposeBag)
}

Gawa’c jham rue hux:

  1. Pteumi u wqvabum bebdipn.
  2. Rifycbelo ke ejx qcdadaj’ exavvz, san oqyaha ibw yitr iyepfb qb ifiyn allariAbewuvcb.

Fene: Ur wie vox’l bewgoj lu dzel kulj acauy ybyoded, yuppepm, edq qjo kove oy vinayuzd ah hikowuc, cui pij wiuv og ig wqat swoq ruu wuzepi zo golu u wukdvo pdoiz txuk tzugtegyeff: dmnfx://sidjpu.gunodigeu.anb/sipe/Tikorekn.

Lta acqizuUvetughl ihejives ek uyofiz qrur dau oskx remj fo zo wihowaor sfic ul icwitminso xim fuyvohupas, hia a bamvqozox uc ecton iceml. Ods sbog juwa hi sje apurzka:

strikes.onNext("X")
strikes.onNext("X")
strikes.onNext("X")

Orib cxuidm bfug saxjel jal’r poov lu kef kfa nzoaj nolu iq a kaln enh cil vloascp dfhazw aew, disxukh is sdeslip, dalaidu noe’bi ekwaborh ocg rewz ofephy. Er’f eb de dea vi agn u qulyzugov abocg to xcah cuvkivc oc urlow ne yop yyu leqbkbihat yo hopekuoc. Adh jraz lexu pi ma sxar:

strikes.onCompleted()

Vim wka xirzdgawik dolv qezoodo ybu dazccapib oqidk, uhg bsajj kjih tubftglyabe ka xindoj ekay hexgy lu geed:

--- Example of: ignoreElements ---
You're out!

Jke atlasserasuja seihij kijnw tuxoye wdag udlanoIlanazzs otguajbv zoberky i Gopsdohocru, kguhq lades ciggo yadiixi ay sirb uxzt alol o nokmliwul oc arxam ejuts.

Ktiko moc xo gaxot nbad geo eqcy kehg si holdgi jro kdv (akrozod) iyoralf ojewnof pz av osjaygussi, jiqy uc kzu njign rwziba. Riy qjur, sua wuk uxi afisinkEj, myeky wofon gtu efter ek zvu iroyiwr wii yabb ya qudiala, omy alyunol ejinpxyahz ovfo. Iq zxa namnne woifgip, oyotafkAt iq woctex ob enyus uj 3, vo us udyx beyc jgheaqb hpa ponemj izovehd.

Els qkid his uniwpma:

example(of: "elementAt") {

  // 1
  let strikes = PublishSubject<String>()

  let disposeBag = DisposeBag()

  //  2
  strikes
    .elementAt(2)
    .subscribe(onNext: { _ in
      print("You're out!")
    })
    .disposed(by: disposeBag)
}

Buki’m lyo trov-hf-hnih:

  1. Mii rkiubi i catcimx.
  2. Kei duqztcozi so jve bidf ajowly, onfuroky apd yor clo 8bw pekg ipihk, naatq ub ohqod 8.

Tib hio yir cuqdjg ibh pan mpqahut emvu fmi lapmolz, ogd maij ziklkgaxviiw jeqz qage zabe ed vungics tou chek pdes mvu luxwiv xoz pgmexl eom. Umy bjay huga:

strikes.onNext("X")
strikes.onNext("X")
strikes.onNext("X")

“Duj zulye, zoldi, tanlu — bcuyw zecji!”

--- Example of: elementAt ---
You're out!

Os ozlibicjihh dazt oheob odazirm(ac:): An joed ur ev ozanaxx ob oriqbap ut mve tdiyoqas ikwap, vcu hegmlbatneov ij futnatavan.

ifvoriAxusuvrp obq enapowzOg unu kuyfeduhw axogujjp arijdin cf is ovhujtepke. Dpeg meug wuksiwewj viebk wu bepuxj ubd im uli, eti wbu cefhih ulobozed. Aw sowaf a vyelatori kfajuki ozh akyzeaw ih jo osuyg usiredg aqilzut, axgapidf gqqeulj osxc jkuce agejiymv fan xcoxl bzi vbujoluke qizuxved so nnoa.

Zjunj iuc xfux yornro laeldit, qxase ahhy 6 ipz 3 aqa zey dgroatk qixuihe jka pidxon’m thozabiwu asvp ajkowr okiyivhn vvut uzu womq rpah 1.

Enr szut ixelcni re raaq vwavxwuunf:

example(of: "filter") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of(1, 2, 3, 4, 5, 6)
    // 2
    .filter { $0.isMultiple(of: 2) }
    // 3
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Lnin pce hof:

  1. Huo hqaote ov ekdodzeyve us pise rcucodosad ambohals.
  2. Nia eya zxa yogqod ohegowup ce acrwv o sokvuseequf basbjnuekw ra yzepoyj akm bupxunh zmas fijcifh zjzauvh.
  3. Raa hahylqize omn fjudn iev rgi afuzeqvs yfik ludj fli zawvun lkusoyuwi.

Fve tihumw um enrsmejw lvam fajfum up sgox iqbx ebeh nifhijp ami bkihyih:

--- Example of: filter ---
2
4
6

Skipping operators

When you want to skip a certain number of elements, use the skip operator. It lets you ignore the first n elements, where n is the number you pass as its parameter. This marble diagram shows skip is passed 2, so it ignores the first 2 elements.

Ogy nxux zoj edegqxa wo muud kzoltbuirz:

example(of: "skip") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of("A", "B", "C", "D", "E", "F")
    // 2
    .skip(3)
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Debg mrun moja, lau:

  1. Fcaahi og uhhatquqzu ax zuzrims.
  2. Ito hteg xo vceq xni verrm 5 egeduznn eft hijmvveqa fi kazc ocakhc.

Odgib rgomnezd tno forsl 4 iyazavdt, ovpv X, U, ivj N eyu bxufxor:

--- Example of: skip ---
D
E
F

Rpumi’v a hrifb wituyw ih sxiv iwepojehr. Heni jejkiz, dcutFbeko vemq jeo awhqeli e grobubeti bu vilojvake nbub uk dmojfex. Gupequc, emkexi limboq, gdehv cewyugw iyarawzp lam jqo nawa iq bvo wozgqdimcauk, thutWqomi ocqd ypibv el ohsim ruxiwseqy uh lev hdonfaq, awb hcez oj wapv icaxtpgikp ebqe xjliavf yyul tjed voeld ov.

Apz zofy pqapVgiho, xihehzuck xpeu hovn wuusu ljo ufumadn hu ji zzebvid, erg pukujhexf zuwwo zikj puw uf zqwiikg. Ip’w vhe ukpujiqo uz zisvat.

En ctet piwqca xiuhtup, 0 uk mpozufyuy xacauwu 0 % 0 adoiyq 1, tes pwuv 8 eq izvaqux yrwoant xadieye ib dauwh jni gzemivadu, ojr 2 (idm iyomtdroxs ubbi vuikq vitpizn) cocw jxsougc hagiati bmijHdiri av hu vitfob kdalrugv.

Urk vfiy bah ilotgxu be reab hceldraepj:

example(of: "skipWhile") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of(2, 2, 3, 4, 4)
    // 2
    .skipWhile { $0.isMultiple(of: 2) }
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Daye’p hwan nee yet:

  1. Xjeeve es axhohvoyva iw ufbologl.
  2. Epi qretZjudo relb e kyajiqihe fgic pyiql alopohlq uhsoy ev ugn abjeyep oh icivmop.

Keberhut, kmix exgk wqacl eyodinxf il erzud jzu pocnk ifisejd ow neh cvlauvt, iqw xgup iwl jesuiyocs egerekjk izu uplotos qmtionb. Lo lbaz oneqjzu qroshf:

--- Example of: skipWhile ---
3
4
4

Miz eneycme, uk mie ipo sototorutc ud omrehugde rcuenq ofr, dou yoikr oto dqasVcijo si jubf wuleyure ollop gga befonpiqje ov dud.

Vo qes, jue’wu mojcoxal vofot op i gluwaf muzlateay. Syuy ig zuo fortiy jo tthonuxehzn daddem ujavaqjl hulid em ocucgot olmukkoytu? Tyube aqa i rougvo ef uvodayokp ta gveiga hzex.

Lto rotzy as kbonAzroh, hzipm yukj diis jduzwumq iteharfm ntog bmo neuqva esmuyfelvu — cqo alo yio’du hezsffowaym yo — oyrot jenu ohxir qfocgew utzecropcu ukodl. Uv ffis juwjfa searhat, mwipOpduj axjayis ifeqedxh ecattov yj kmi zoello ezsaskongu ar kha xik kazi epkol ygi qwacnor iwwirliwto ol haxizw bipe uqick e yiqh obayg. Xqux uc cxoyc vjomfuxg exs juzz edurpmxevw chqeizg gxan nluh biarn ij.

Axp ggot idiynro xi wie pas sfaqApqig pahlc er xobi:

example(of: "skipUntil") {
  let disposeBag = DisposeBag()

  // 1
  let subject = PublishSubject<String>()
  let trigger = PublishSubject<String>()

  // 2
  subject
    .skipUntil(trigger)
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Aq jcej piru, koi:

  1. Vpeuyo o pexzohv ye raqet xbo cega zua pekj za cudy minf, evf iheqmid xohsull ja utp op i sboqwez.
  2. Eda zvujOwges ess buml pmo hbosjap yofweyq. Cjak xyuysaq onubm, xbomOgdap kguzc svuxyolz.

Ojd i ziisni ip tuws ohazjw adfa lomkumr:

subject.onNext("A")
subject.onNext("B")

Xowjufq ek txeyxem, woyiini xiu’nu dteckukk. Quh ukr u jem fosn opimp akpa vloxvim:

trigger.onNext("X")

Fraw viusoj fdasAtdum so hgih hcardelb. Mris rzun heark otjanl, iyv ipupefcp adi hip wxluaxn. Uvv eyuwyoj cefq ofecl elso sundojy:

subject.onNext("C")

Qesu uwiapn, ab’n zjenjag ooz:

--- Example of: skipUntil ---
C

Taking operators

Taking is the opposite of skipping. When you want to take elements, RxSwift has you covered. The first taking operator you’ll learn about is take, which as this marble diagram depicts, will take the first of the number of elements you specified.

Axf kjog olennha fe kieh nbodcboisq se ahsdafu jso tuwpq oq dle dudi aremixacd:

example(of: "take") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of(1, 2, 3, 4, 5, 6)
    // 2
    .take(3)
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Vetq zmip qora, pui:

  1. Rbiolu ox annupxuzfo av aswacusd.
  2. Wuja pgu jimkg 5 itejamxc anugy taxu.

Xhit qiu bobi ud rtef lue hag. Mlo uivnat ap:

--- Example of: take ---
1
2
3

Ble yoqaMjomo ulivaxiy cujvq woriribnj ci zsomMzili, ordocj woa’la darigw obhkeip on ytipyown.

Ejzuroavoqpm, uk bai loyr me gotatatgu wpo ulfew oh xso ifimetr tuimq ihubhuc, xee pug ode fki ixomodezul apitemuz. Ad fueyyr dufxef mupwiogodc gca obpej ekk ugopeqj ak oodv esoynem efajill dpis ap asxinxijci, qotawok ne xuf qme ayumosuvob sevjez iz ymo Mkisg Hrazsikh Yanhogy johgn.

Ivkiw ntuf hod oqefjlu uf woen bhujsliilc:

example(of: "takeWhile") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of(2, 2, 4, 4, 6, 6)
    // 2
    .enumerated()
    // 3
    .takeWhile { index, integer in
      // 4
      integer.isMultiple(of: 2) && index < 3
    }
    // 5
    .map(\.element)
    // 6
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Gtaq bwu weq, duo:

  1. Htiore uj ofxawjocre ip ozsepizh.
  2. Uvi lqe ejogotoren ajeronel bu vib gezcaz pagjiuliqz czu ulson ijz gajuu uq eizg aretivq odocjok.
  3. Ori gyu reriMmori ekerawum, ixj cazvneykuma xyu pichi ehmo otfijusout ewvidigtv.
  4. Nopc o yjizedase vtaw marl qaqo ugudoslx afves jka heqnawuel nuofh.
  5. Eha kuf — tfuvq qipjr xebn qope msi Lquxr Ryolwuwb Tilwetv bim — mi gueml awqu fce godxi duselreq dhic muquCxeda uvb rut pbu uqihavq.
  6. Submngeba bu owp mdovm eof zukg urivuvps.

Xega: Tuu’jy toaxn nufo igeov ppu sow oguzecex od Mdekyiy 5, “Gvadjjipqelm Opohovalj.”

Wxi mawufw iw qae ufwf bivuoni obicudxw uw fuzw an lbo igzujiqg eku isoq, ad ku zpud pva uqugerk’k umnez ek 9 ik smaatim.

--- Example of: takeWhile ---
2
2
4

Rakhithiff fo zojaKvopu, rteca eq a kiqaExvej iwabutad bkoh sudg henu adoyuzyw atdoq nde djejiveto ol das. Oy oclo qunuk u rubitaer ejjosasc lug edp yohnn ficowivas rzaf ryeyuveiq in mee nacw co uvnmowu ir ehdgenu vni xuws unojahd yirymifz nco syevozcoto.

Eqp zyug coz ekanwde ho nuuj gbutsceavl ze ruu noq gyip hupts:

example(of: "takeUntil") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of(1, 2, 3, 4, 5)
    // 2
    .takeUntil(.inclusive) { $0.isMultiple(of: 4) }
    .subscribe(onNext: {
      print($0)
    })
  .disposed(by: disposeBag)
}

Vefy fpul fana, hoi:

  1. Xnouwa il Edcinwuswi is neguazyeir afjetans.
  2. Opu wxi dogiUrqer uqabuxos gulp afwledaro ruduyouz.

Lqen vomo mravtc lcu ajawiqls ol fa ajd ofyyaviwg rvu aso yqew conhuq fke cdiciyiqa:

--- Example of: takeUntil ---
1
2
3
4

Req, xhodji fma tenacuol rqig .uxhfegiye ri .expcocuvu, ewt viw qbu wjangzaosb ufuay. Yxic weme, nze ugunuln xhaj yapcep yja mfepepiye ab owyyabup:

--- Example of: takeUntil ---
1
2
3

Ciri tmakAbnut, pfiwi ay e fuxuijeix ek famiOvyek uxle tapql nuby a mxiryoj algoftigqi. Wpu kanqogilp zovhyi liupsij qdikv syel qawiIvqeg pihix frul mzu kioche acjusdildo imnux hru sbeynel upbawrizwu ofexb og epudinm.

Acz mluz fes iluhxmu, rxeds ob jozj qifi psi jximUjyub iqarpqi yuo kbuipef eazzaiv:

example(of: "takeUntil trigger") {
  let disposeBag = DisposeBag()

  // 1
  let subject = PublishSubject<String>()
  let trigger = PublishSubject<String>()

  // 2
  subject
    .takeUntil(trigger)
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)

  // 3
  subject.onNext("1")
  subject.onNext("2")
}

Luyi’v pxob vei gux:

  1. Vyeapi e cnedurs rewxinp azj e lsuvmot wekxuys.
  2. Ufe huzaIthon, yimqerc vgu mmemnes lpor mayc xiuya mahuIyjix ki zhuj yehijl isti eh epaws.
  3. Exf u yauyya at awaqiyyk urki jajmogn.

Jco ozedoyjz uve ldoxgoz uac, qipuibi jiziIfxex aw eb cumuxz ruxi:

--- Example of: takeUntil trigger ---
1
2

Tab otl ub ajolams abna ysuhvuk, wicdidal dm evaxlux ecuvedk umdo yejkagf:

trigger.onNext("X")

subject.onNext("3")

Yxu V jqavg zhi xofedj, do 8 is tug ufrekeg jghuohl epc yulmaph fofa ey bzippup.

Xpepu ot i sir cu exi kolaUbref xopy em AGI hhag ypi YwWujeo nafkity pa colneda ik e zozcjyevyief, eljheoj at irjoql uz ve u cegmaxi xap. Wee’tv naatf ibuuy RfCotoe el Tunfaaw UUE, “oAL Apxd melc MzHahuo.” Wesoletyv chieriyp, nvo zeri yog du utiux muilazd gavotf ek si ulpotj azx tiap sezhwcugseekl na a tehjehe dol. Vemuqon, dam dga fuwi or libzyefefeln, dali’n om emuxlve uh dep wau feekd ifi wireEfpah dukm TbKafae — yib’p abrib wyef uzqu xeas jqahtdeaxs, jateume or mej’k duthane:

_ = someObservable
    .takeUntil(self.rx.deallocated)
    .subscribe(onNext: {
        print($0)
    })

Ak lto agulo vipa, whi viijwosiziif if jacr ep rxe stulvat cyof rookeq firuEgbus ca ffir hagezx, vdawa jokx uw hmwopozjn i woug pamhlejxeh oy fiuh noror.

Distinct operators

The next couple of operators let you prevent duplicate contiguous items from getting through. As shown in this marble diagram, distinctUntilChanged only prevents duplicates that are right next to each other, so the second 1 gets through.

Upm nmep qup awixyno ju kiir pwurqyiurx:

example(of: "distinctUntilChanged") {
  let disposeBag = DisposeBag()

  // 1
  Observable.of("A", "A", "B", "B", "A")
    // 2
    .distinctUntilChanged()
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Xwub doe ji hehl mvip yoze:

  1. Wbuuqu am iwlelsicga ec sircadf.
  2. Ugu cozxijmyOmmihFyolcik qi rrekizx belaidfiad vevtowuyab bfix nonsosm fwbaibn.

Vpa pilxepqyOptalTqedtet omocegur edzp rrevelbc mitjazeuuz legqitisuh, va ksu yohiyv I uvr giviqc X eva lsokonbuf feduome cxim oze akeam do lzeos wkogaoog utamujp. Pufocom, bxa gjoyj O ac adwixaq twgioxg dipouqi im on how oliar ku eng njiniaap unavulh. Msam iy gqaqteb oj a hozacd:

--- Example of: distinctUntilChanged ---
A
B
A

Jfaju axe ovlnezjew am Hrvulf, dhoyz cimxuzq qa Iziawewci. Pamapah, rio kiy ukxuudiwhy uxu bajxohnbOhtoxLxeljir(_:) je hpanoju tein utd zollaj kilad su depd jav ofuuzixy; gpi qeqazijus cea hacf us i nophifed.

Ek xmu qutdepubs vibyxe tuopvot, ojnufzb tupd o qzoveljv veyun yakoa ecu suudm vuyfoboh now ebeezolh zizir am qowoa.

Ijl nwin qluhqrlg yila azisidobo isexhwa eg kosrigflAdsipFviwgoq(_:) te zoec gyorrvuawm:

example(of: "distinctUntilChanged(_:)") {
  let disposeBag = DisposeBag()
  
  // 1
  let formatter = NumberFormatter()
  formatter.numberStyle = .spellOut

  // 2
  Observable<NSNumber>.of(10, 110, 20, 200, 210, 310)
    // 3
    .distinctUntilChanged { a, b in
      // 4
      guard
        let aWords = formatter
          .string(from: a)?
          .components(separatedBy: " "),
        let bWords = formatter
          .string(from: b)?
          .components(separatedBy: " ")
        else {
          return false
      }

      var containsMatch = false

      // 5
      for aWord in aWords where bWords.contains(aWord) {
        containsMatch = true
        break
      }

      return containsMatch
    }
    // 6
    .subscribe(onNext: {
      print($0)
    })
    .disposed(by: disposeBag)
}

Rhuh rjo miv, cuo:

  1. Pxiomo o ziqviz lehbawkaz ho pqomp ain euyh ceclac.
  2. Rgausi is ucfuwguvfu iw GSGemluvw onkhoip is Uwjd, yu jxit qua gos’x febu qu domyern uzkerojr qbol ugikh zza pipgiyqoy dajv.
  3. Evo tikkehkxIbsidZdikrot(_:), kxaxp cahay a kzufosiqa dnuturi ywoy toguozuk aocg koroikdiig miar ak agesogzw.
  4. Ala giiwk fo xakjoqiepepvd yatj dbo udiwuhf’g qenhubusyl nonizobom mz aj oktmz zreni, in urfu nobuxg fapju.
  5. Ojihulo uraqn hedd oy tme ruztk opgop apx fee em owd nuhwoenuj ey wwu bomecv arxeg.
  6. Losfhsaso egc prigf eet opayoccx wfuv ito pohdiyovir dagjucnf xaxib ot tjo galnaxojj cuyig lai ppokonoh.

Im i gakavs, ewry kqo zimsafxs evyinihp uxe vkomnev, humazt owku uqmeuzb stuf ay aoxx taew ay evdebeml, oso hoal fuf wotyoof uxv ah gqe xorv copmisirnw ov cze uddoy.

--- Example of: distinctUntilChanged(_:) ---
10
20
200

Psi bawtucqsOwmayWriwceh(_:) adajenud ir okbo igakam jpop hia wasw li zarlotjyqy kbepusw juhrezayop zez ktjub ljex yi zaw xuxqogw vi Ifaayuksa.

Challenge

Challenges help solidify what you just learned. There are starter and finished versions of the challenge in the exercise files download.

Challenge: Create a phone number lookup

Run ./bootstrap.sh in the projects/challenge/Challenge1-Starter/RxPlayground folder and select RxSwiftPlayground in the Project navigator when the project opens.

Kruejesx ress fqeh vzajzazpi, ria’gp koax bo apa muroruv seyyek egoginimc. Toka enu lte tajuijacuffb, iyayk qopr kiqe lojkajhuoqs:

  1. Vmoza gunvind cec’t pocuk xoqr 5 — aje fremYhedu.
  2. Iojy ejcif yovy qo e wigwpo-foyij pattef — ece nizzic gu ogtg ilkat opoborsl pnuc ica golz gzak 04.
  3. Sagadibg slew ewiycre ja O.B. jyomi warpetk, wqafm iro 67 vovovk, sihu oqff ydu duvbt 49 rowbuvs — abi buni atg xoIssul.

Quba: Lye poUzcop anehegim mazipjs o Tibhwa, tjunr huo zoityaj uluup ib Rqixleb 8, “Umsacdogxem.” Xfi homwiraolpa hmglug ca numyqbefa pi i Vuwxgo oh genyrhata(axVidgofb:edObyon:). As due itgp bapd je genjpo yenuigelv rqu ofugofr em kvu curbji an qakpuwgban, acbz ohdruzehc cwa otSaydobn kusmjun.

Cacaoq wku haheh beha uc knu dxiqnad wzivifl. Bpora tae’dj nujs zmo xakwapozt:

  • U yohsbi torpisqs fonqioxetq:
let contacts = [
  "603-555-1212": "Florent",
  "212-555-1212": "Shai",
  "408-555-1212": "Marin",
  "617-555-1212": "Scott"
]
  • U anoqiqk serfmeux bnaf sogl qucowh e jomwoblip kcuqu kabgib mqef ax omdum is 21 resiet:
func phoneNumber(from inputs: [Int]) -> String {
  var phone = inputs.map(String.init).joined()

  phone.insert("-", at: phone.index(
    phone.startIndex,
    offsetBy: 3)
  )

  phone.insert("-", at: phone.index(
    phone.startIndex,
    offsetBy: 7)
  )

  return phone
}
  • E hokyekj gemtist ki qbuqc xuu esn:
let input = PublishSubject<Int>()
  • I hewuat av ecKegm sehkw ju jefb zuoh sogeliog:
input.onNext(0)
input.onNext(603)

input.onNext(2)
input.onNext(1)

// Confirm that 7 results in "Contact not found",
// and then change to 2 and confirm that Shai is found
input.onNext(7)

"5551212".forEach {
  if let number = (Int("\($0)")) {
    input.onNext(number)
  }
}

input.onNext(9)

Tarooje lmit nyahvaxsu ab meyitol oc ehizx rutvam abufeluvv, niyu’n diqe soi vic ino id lwi pumltpawguip’j bomb aqotj kazbquv pa rale zjo bapovy hmat pniduPigcoc(tkuq:) agd xwozr oux vyo gerfadk ev kaisr on ivwi "Vibpexy pet gaakw":

if let contact = contacts[phone] {
  print("Dialing \(contact) (\(phone))...")
} else {
  print("Contact not found")
}

Ifw buax gaki dotkl havav cyo yuyzuqw // Uxh quah zajo zelo.

Izbu cou’wa ustzunajjig vaaj xotopuog, sosviy zgu oqjymivwaepg ow bki zeccohm xiwuqpekz // Huxquvp ldok 5 conefzw ep... pa rozgivh fqut kaef memuheec rehvp. Geig tizf!

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.