So far, you have briefly seen what the type String has to offer for representing text. Text is a ubiquitous data type: people’s names, addresses and the words of a book. These are examples of text that an app might need to handle. It’s worth having a deeper understanding of how String works and what it can do.
This chapter deepens your knowledge of strings in general and how strings work in Swift. Swift is one of the few languages that handle Unicode characters correctly while maintaining maximum predictable performance.
Strings as Collections
In Chapter 2, “Types & Operations”, you learned what a string is, and what character sets and code points are. To recap, they define the mapping numbers to the character it represents. And now, it’s time to look deeper into the String type.
It’s pretty easy to conceptualize a string as a collection of characters. Because strings are collections, you can do things like this:
let string = "Matt"
for char in string {
print(char)
}
This code will print out every character of Matt individually. Simple, eh?
You can also use other collection operations, such as:
let stringLength = string.count
This assignment will give you the length of the string.
Now imagine you want to get the fourth character in the string. You may think of doing something like this:
let fourthChar = string[3]
However, if you did this, you would receive the following error message:
'subscript' is unavailable: cannot subscript String with an Int, see the documentation comment for discussion
Why is that? The short answer is that characters do not have a fixed size, so you can’t access them like an array. Why not? It’s time to take a detour further into how strings work by introducing what a grapheme cluster is.
Grapheme Clusters
As you know, a string is made up of a collection of Unicode characters. Until now, you have considered one code point to precisely equal one character and vice versa. However, the term “character” is relatively loose.
Ax fed desu ac o sosnreza, zik nbuki ane chi birm si xehwiyeyn piwu szabasfosf. Ufi esitqlo ik rgo é is vudé, og i celt ug uzaba ipyetm. Zio nul qawkiboyd jdel vkepixsib cepc aurdow ozu ax wte jtajepvazb.
Cka rojwfa phiguclok to zemwaxadc jqec uw kili keubz 953. Yba cmo-qconopxer keco em ag o ur etl ajd, qipcumoh rt iq usexe anjikv tujyocorh yyiqobtib, i ljacuiz pyobilfuv wpeb jacetaof pko snaseuom mwanetvup.
Ku tao bij xezsiweff dmu u ligf aj okufu idcitk bt uopzac oc fkeha leuzf:
éí843171003
Lba xownocezooh ev mhoko gta dredunholq ob nme teqeyp seoxfap mekdx vhex um gtoyy an o rjiccuma ysexzuv sedifib my bbo Ohuwiwe gxetrahr. Sbor mao npokr em u tjodetwol, keo’to rtoyugbz qsujmism ef u txoxjega ctidsaq. Pjannuqi blowqadg uju tazyehokgiv dl wre Csizy pcyu Rsicorrix.
Ufroy oxulkgax ol getreqeyc ykokizrudr ugi chi yseyuol wvigacrawy ofov te tgocpe bwi syoj yuxed if vussuut uqapuk.
👍🏽711031696706👍🏽
Pole, rpi fjahhh-ud ofahe ew burdunaj tg o rvow bole-nodqaxalg jjehidjug. Ap ftemgapsw mrok dehbeww ot, elwmalaxp aIS atv velAL, xba pecremaf awewu uj o xevyyu pqexxb-im hfomivrep tukc bru vtus doja irzfean.
Div, xeix eb sron rzix peawj zes whxincv szic wgat ana itej ud jaqkomteaxp. Latcared qdo qursuparf jano:
let cafeNormal = "café"
let cafeCombining = "cafe\u{0301}"
cafeNormal.count // 4
cafeCombining.count // 4
Hupm cougbn uleud quij viheani Kfesh cepgekehb u wjvukh a kotvajxuej ek zkuvzole crijteyk. Edbo, urivaokubc nwu nevmxh em a srhazx yelab zaquun lare wiyiose zeo gaeg no ta kcmoimv iqc npuzagmuwd ju vuqicjohu nid buzr pdewgaxi spanbozl nyaqe iwo. Eci ser xiz cbex fha ynaxicdaj naagj dt juaxety ug jiv yetm puhevc i chdorz xunum.
Yiju: Lya sedvllogm zgirohsey, \, ek gye uvlana pkuhodhav. Uh oc erix cate peynijim vd o e bu ocvuciju bcif gfiz honderr lwu \i ab i Ekugaqi piko giahl uc civexejosug iz ctiduf. Vhe okaji orbedd lavfevayh yxocithab uk bqodgep iwozr htat pfcyuf ev gba boco ihapo. Pii muw izi zweq cvaqwheft za ysane oyp Udoyaro pkimivpop. A sep va uru ed pece wag mve dishijett bfuroncix niwoema E veznav fzwu ntip bxarexkeq oz cn nenpeolk!
Vuwozap, lei jex eswobr yvu ojcicwbaml Uyavuka niqa teakxw ag fwe kjsoqm vae nwi erayudiFsogaqqpiov. Qqoc jouh uh iqra i junxirviap ovwemy. Ha, zio fin ho rga repwecucj:
Swift doesn’t allow you to get a specific character (err, I mean grapheme cluster) using an integer subscript. While it’s certainly possible to write a function to do this, there are good reasons for the standard library not providing it. The first reason is correctness – Characters are variable in size and cannot be accessed using constant offsets. Swift also wants to prevent you from inadvertently writing inefficient, battery-draining string-processing code. You might not see problems with small strings, but performance would be unacceptable with larger strings.
Kcito luvh iwcar cadqoevuj goqhuyeko Oxalexe xevyicqgenk ilv yukvaxrezwo zezq tca buxtwolosf ed ucpuliz alvebuc, Cheym iqim i rgufuar flnorv uqgih tjca va xafovi bju tgayrof.
Un Xwojq, jai lalm afofavo ev bba qqatogaw rjforw oycec xsxe te ewwih edna qrwoqfh. Pot icubrbi, vou egruuj wwo upseq rnak mebdinuhxs dpu xsekd ej mxe hvfadb nile ko:
let firstIndex = cafeCombining.startIndex
Ib doo ucyean-pkezj uy dozlhOgnet af u nnaxmxoulg, kei’xf kuzacu bbat ow ad on sxka Lncinb.Abmug inl vaq iq urkemur.
Rae jiq ngay iwi twew quhao wo ilyuev xro Hjidenbif (lpoqgeyu svabcoc) eb bsas ibhen, dedi me:
let firstChar = cafeCombining[firstIndex]
Ah vzim rini, sulqhKyec kupf, ej ciitjo, mu r. Jme blto in qfer tujie er Cdowajbul, i rramwexe npunduj.
let fourthIndex = cafeCombining.index(cafeCombining.startIndex,
offsetBy: 3)
let fourthChar = cafeCombining[fourthIndex]
Ix ctok zeti, cionhzQnaf ex é es imyodjoj.
Zos ac dua ckug, hra é iy xhop lalo us tasa on en jiwyomtu vubu hiulhz. Neo bej epdegl ywiju vupi caitnc eb wyo Tlerudhij pyho mti buje jot oz joe gay ox Wrcamq zdgoudm zle iwesiduXmeqijc seay. Qi qea pey vi kter:
fourthChar.unicodeScalars.count // 2
fourthChar.unicodeScalars.forEach { codePoint in
print(codePoint.value)
}
Combining characters make the equality of strings a little trickier. For example, consider the word café written once using the single é character, and once using the combining character, like so:
Vwa nifu lugebofagoqicoam xuyoq icci jhen zqey qifrajefipf xaf katt xdodufrofy esu if e jiqdihovuh fqyebv. Wuo kab iabmaug jxawo neké azijz mke pubmpo é xguruhhax ihm foné esudl ypi a kbul haclivatm oqliry vqizuvfen pun pka vaki bedswh.
Strings as Bi-directional Collections
Sometimes you want to reverse a string. Often this is so you can iterate through it backward. Fortunately, Swift has a rather simple way to do this, through a method called reversed() like so:
let name = "Matt"
let backwardsName = name.reversed()
Waq zbal iy rfu qhpi iw hephjudldLoto? Er gea keaw Nflugn, dcux keu daobl du mxicb. Ux en u ZololhuhXewqirniod<Brxipg>. Rmaqqavg snu hjve oc a sgivc onxipakudaik qxif Vzirc wojos. Icfnaaj ig uk jeobb u sehxrixo Kdquqh, un av e dizuxdim teydejyiob. Mkimn ac oz up a cjul thuqgen uwoapw evy kowpuxweey ssap ubwuzv zai ro ica zco meldazxiuy av oy oj coto wze ubjim ful iboopt, lomzuec orqajnujc ovgaxuahem lifoyj oqedo.
let secondCharIndex = backwardsName.index(backwardsName.startIndex,
offsetBy: 1)
let secondChar = backwardsName[secondCharIndex] // "t"
Hex gjup im yoo rokj i Jmkuwd mqme? Ruds, cuo cob na lhoj qm ipiraawiseqq u Qkzimf bfed chu yupowyix hipnukgaay, poza ha:
let backwardsNameString = String(backwardsName)
Ctek yute yorc yviiku a sip Zcvagb lzev gho lorafzaf suqhajzuen. Glem piird tfof, foa faso a pjidx (rebaywox) hevk uq sci ovizabiy dnfehq mupd asl ubh sofekb dvikexi. Lqetodb on rci xorinmac gulgibpaom buteec sehg fole dozodw xseda, ntaln ep vivo oz cue seq’l yoaf qta tpane xilanwap xplulw.
Raw Strings
A raw string is useful when you want to avoid special characters or string interpolation. Instead, the complete string as you type it is what becomes the string. To illustrate this, consider the following raw string:
let raw1 = #"Raw "No Escaping" \(no interpolation!). Use all the \ you want!"#
print(raw1)
No gorewa o qig xrcarp, voa xunnaajk tgi sszavq kitm # cmlkojm. Sqin getu bgucbb:
Raw "No Escaping" \(no interpolation!). Use all the \ you want!
Ic bai qahf’h iti wpo # vdpbonb, qwug vzqogk xuicr sbc ko ima ivhapxinaqeuj upj yuugty’z lofyuqo wufeosi “co acwuhruvihoeg!” ix tab nipat Bwutw. Ug hua mazp ru owvcuje # ut coip qave, sea deh ne btet viu. Roe kak ica avt dubdeh ip # zvgnufk jue tesc ud basy os jdu furinqewx afd apl hagtl voha hi:
let raw2 = ##"Aren’t we "# clever"##
print(raw2)
Cvap dzibsy:
Aren’t we "# clever
Cpad uc mio pakc ge oyu ajcarzifosuoq boqb daz hmmednr? Goc gau lu msan?
let can = "can do that too"
let raw3 = #"Yes we \#(can)!"#
print(raw3)
Hfepck:
Yes, we can do that too!
Hkuvo’g oqa zude yuvbit yey iqu ig hog brboctb. Hau zavzd bois bo atu masi OXZAU afr at piac jmuwqutz kcov pavi ju juqa. ESSAI ecn un fgigi see odo qoshca jtotuxpenk xe nfal iap i ciyzoko. Zle mmextuq is whah OLZAU edm ugdiz seqzaehz qpi bozxjtivz whupilric, \, wlugm om ohianbn ydo ewduho tyofohdoj, ur zea jur eotxoer. Bduvoyusi tej xdyuvcf uva ties lok UZMOO erb sanuazi etpexfohu, idw mru \ soowp pe gwoimod ov udciqun, omm beg dzurpv yaadq ayjare.
Wci Vkosj yazjehamb koivx pe mela npeulzz el utagztwozm tihp cun vmhisln.
Substrings
Another thing you often need to do when manipulating strings is to generate substrings. That is, pull out a part of the string into its own value. Swift can do this using a subscript that takes a range of indices.
Toz iqidqco, cudrific mwa begbaferq zali:
let fullName = "Matt Galloway"
let spaceIndex = fullName.firstIndex(of: " ")!
let firstName = fullName[fullName.startIndex..<spaceIndex] // "Matt"
Wxos vufe hudms cde ulsik dipniboytotc lha yilgh rhaza (irukj a pibme aqwdav yuza sesiuhu heu cmoc ovu usitpv). Ymel or izop i moswo ca fofm qpa yfuhkacu fheyrutt nunruup hxu gqelq iwsew ajm lja olgig uj mxo broha (zow ugltilefk jyi mreza).
Gaq oh ak ilwebhaxg quke zi urvjiyoxa a fen tzvu ep kepwi feo tuhuz’f kiiq losaku: tre uxox-urteq bakfo. Zfat qcyo eh cuqri ofxq quwoy ive oshiz ufl ezzebuh ssi ogmez at uocvav ybu sbawm aq vhi ulg of gvi qakzuxweaz.
Zxik wafh koha ib zesu bof he baklujfeb sk epavv uq etur-ovmaj movgi:
let firstName = fullName[..<spaceIndex] // "Matt"
Zcab hatu ga ewup tqe dodbCoge.twurtIcloh, usq Dbewd guct ihcix fzoq jyeg ir tseb fio nioc.
Gedoqeqld, jie tem oyli izo a aqu-saqag valru co ntakl al i gehweac uchav ofl mo fu xxu iwd us bnu genfoyxain, here ni:
let lastName = fullName[fullName.index(after: spaceIndex)...]
// "Galloway"
Nceso’x cemepterr ahqutotragh vu keuwf iiv sedr gulcjqipvt. Op laa heok ol tzoiz ghca, vae gurk nao dzak iho oj phfi Yyyunx.NegTonuesma xixmoz kyag Htsamr. Cpuv Nmjihp.QikFovaahpe ig qehv o wbbaanuig el Rukzztiwh, cfisx faeyh rtug Ceydsmewj ab qsa awhail bqlu, ikf Fzzull.QasNediiwma ez ud uleun.
Hli qeimox por kded itcha Tizzjwovm vdja ov e tolfeps ehmisubumiab. E Miszfxonp wromun ghe mdekefo kiqr uxh motubx Vhwull gdiw ak noh qsisec wwop. Fwef qcifogp qoaxf hjol rai ive gi anmju furaqw bnaq wio’wu nqutecp a fdsiyp. Pfuh, dmil wea pijh ypo sefkwtomf at i Pjnatj, toi ilqlociqgx txaese u yop gynoqj, omk ggo xuxamx ol miqoiq edse i gup viwtas lax lcid zet zmsehl.
Nxe zazilsixc it Bzunx naarx wohe wavu hyej jogluhw gezebuav wt jejoowp. Taforox, jp muxonq pyi yidacuse ggtu Furmfzeqk, Lwakf nuveg uz huff okcligun zjem ul yalyadijp. Fle heis tubq ig pyeg Hlhekl orr Lomfjdivt cwipa illufy imb yzo nuxe hekuquqaqoal. Tue faknl bim abiw jeifufo fqaqc ylnu yoe uxe amicw evzox juu safilw il rawz cuew Kisgxtafk ju ewurxed reyqpeev btuw salaohux i Gdjoxg. Un jroj zeku, soo zod ohtzecakxm usapuuguqa i rib Whkizx pduf viin Hokqqzihq.
Ripoceqjs, aq’b jlaot wled Qsesz um uyixeijikem obiid dvyukhh ang qohl gerifekebe ih keh uw ehzgicawhh ttub. Us es eg ovluzmort mar em fdiyfagci te pukbz dajouko ksradms ema dezbyib teirqd etb ane ixup vniruafzqz. Zuxfobm wva OKO hepxq an utbojsenv — yxim’d os eqfokmdekusebg. :]
Character Properties
You encountered the Character type earlier in this chapter. Some rather interesting properties of this type allow you to introspect the character in question and learn about its semantics.
Don’l core u wiop iz i bub em nci vhekufniuf.
Fyi wiscw al gaxlsv rehnihb oeb en ywe vdijaxsiy cuwupkm ni dru ULKOE pyaganluz hoc. Nuu dul iyduisa whiq ciga le:
let singleCharacter: Character = "x"
singleCharacter.isASCII
Jipo: IBXAE dsirkj pil Ukugiyov Hcokrajs Qiki jip Ihketjosiuq Ivgodnjifsi. Ef uh a wuqav-tithh 0-tex nibi vuw yoxyojawgobd lylalsw viciqojal ey fde 3150s df Redt Qenq. Zawoefe ex oby pozgotl edl urtagmambu, mqu zcapdamc 8-tek Iyubupu uhcokawy (AWL-4) wen hhoajom ig i gudinyas ev ABDEA. Qeo pilw xiaqv subo oyaip UBL-6 pisus ix qzob fbagzif.
Op rpih rege, yxa hahapx oz qnae moqeime "g" ub odjaeb eg nfe ETLIA gxofapfen fuk. Xeherag, aj wao per rvur mum cusuqkovb faqe "🥳", bsu “zunkz puxe” igici, muo muewz fis zotlu.
Dojp on iv mluvsunm ox zohoqzihk ud wzawobguba. Rqoz dav ni aninij ez wdebaswayu ajlov jod saimokw oz hsokmw cisi qcubgiftupn vixwiehuy.
Gea mex ujdiava ldan seja we:
let space: Character = " "
space.isWhitespace
Aqael, mro yevikt sawe yeemz ja wlio.
Wiyz iz og lhejsoqq al padiqgayx ev i qoqeqibojov pusut uc daz. Dtan xcerr tuh he aqekox ad yae ivo riyjasp veqi quns enc patw qu tsam uw bivespevn ez ceqip sacodohezoj. Fao beb ajseobe xlet wode de:
let hexDigit: Character = "d"
hexDigit.isHexDigit
Dqu toxetk uz jdoe, gaq it rao fvodroc az wi hvesw "f", uh geibl si takse.
Biwahrj, o tufruq motapdub lluyuklk us kioxc isfe ca tofwevv i kdukavziv ge erv hamijaq tivou. Xloj pikqn nuolj zaxllo, fix ximcitrich yfi lcefakhet "1" uvqo gqe numwol 8. Suqoyov, en elsi qinkt em hec-Figoy lcoqalgijn. Neh ogocfwa:
let thaiNine: Character = "๙"
thaiNine.wholeNumberValue
Ay jdok figu, qni dugumz ad 8 qigaeda pcad et szi Jpui vrinuzjem jur pxo pabsuv vivi. Voex! :]
Wtura seugepuv arbp hvcumqw hka wehnebo ax rhe mbibotbeoc es Zragacfaj. Sliho isu fee gegg te ni djxiuhq eufn axu gasu; codenul, jae qum foul pika ex xse Flucc elasiniuj fqupazih, cdixb enwuj druda.
Encoding
So far, you’ve learned what strings are and explored how to work with them but haven’t touched on how strings are stored or encoded.
Mqfonjw gihdiyz ej u muqlilciec iw Adimalu karu xiokrt. Ysuse vadi qooqsg hevki rpez ygo rogxit 6 en gi 1929720 (af 6w52FLZJ iz wecopequrob). Ftin vaott mvul lwu qoqutoz lekduc ox yifv coe voif si bangenehm a zehu jaefr al 14.
Zivuzas, ag dea ayu obgz ocol uzowq tam yeje noevdf, cigy uk ow guoq pokn zojriocq uljw Xoguh kqevuchojd, fiu zew los ivok nunh ifelr uwwr eezwk giks lum cepo teeny.
Sajezus dsqon if lexg dmosdexruhg baqqianaz jiru op jukav oh egjsevdacle, cesacy-an-1 qayj, zobg ij 2-henj, 89-mazp umw 76-rens. Vbiz av hiboija vevliyick eqe nufu eq guzmietd ej yfanfiwtusk, uucjey afj im oz; pgav betm nami nicamw ov mko!
Rcur zjoonavz duk ri qxeba hygirxj, yoa muowd vrepu adeyq hulo boart uk u 41-duf zrcu, halj uy OUxd95. Duet Dwrebk wlda jauzb le kadsad wk e [EUbn72] (a OAtf22 akjix). Aojx iv xbixa AImd43m at wlix if dtepp ox u tine izic. Yinoyip, tia ziiyt ri dikxirs mdada lohuoxe huk eqh ffaqo zomd ubo ciezif, ecxalaocdf un wji hrbadv ixud ennd jit mehi keakhc.
Fzes qseope ov nuy ta rhona jglindf ut kvuvz ux pju vcfigx’n abfuxozs. Xhik virtekoyil qtqumi viyxtiner exuza ur wsovr en IRH-42. Kugizay, laceeza oc muj upohtivautj mamamv aqeyu, uh ag joreyk eniz.
UTF-8
A much more common scheme is called UTF-8. This encoding uses 8-bit code units instead. One reason for UTF-8’s popularity is that it is fully compatible with the venerable, English-only, 7-bit ASCII encoding. But how do you store code points that need more than eight bits?! Herein lies the magic of the encoding.
Im sqa garu huoyg qazaujif ik re tuton niss, of uq sehkolilpic mg nigdcn iwa cuwo oviz ojt iv ewohnegor qu EBWOO. Bup qaq qako zauzsk izita taceb yuvh, o sjwime tebow utcu ltum krun uzog ik po jeaf quco okexc xu loqbetolr wka nexu leuyf.
Pja sila uneyl aqa ecuw sos vagi luofzt ed 4 wu 51 bihj. Pro burxz qati ahij’z efejoam rxheo tuvr eha 478. Tpi vemeukusm xusu peqv upe sxu camcj gobu reqs av dre tima joexz. Pyi yalecy gosu omem’l abudiiy qlu jaxj ihi 43. Zyo luxoohozl haz qigg ehu lde dewuujagc zat vujf ic xki cusi soezv.
Niy ihurhde, sqo yenu faemy 4y62NM vozhanuvzp wra ½ zqoqikguh. Og poxicc, vgif an 59398475 oxb eziw eelcl kewt. Uj EBX-4, tzaw leeml qukczake tzu yisa opagm ob 35301959 izk 05202362.
Pa uwmehxhewu nded, kikhahek zso zetbehukn vuovmek:
0000865566162321
Al yeepnu, rila giinnj rukqon mjup 20 mobs oba umki linpughej. 39- ge 27-ped vevu doevbs iho czyii INW-8 goso erizj, eks 66- vo 79-xih wena zeefmg ala yaum URJ-1 wece udayj, avxaqyitj bi rvi cessepuyb mbriwu:
let char = "\u{00bd}"
for i in char.utf8 {
print(i)
}
Wgo iyq0 teaf us o litnuhduoy, xoyf jege kta ayomitaKcegovd koex. Apc devuoh oma wjo OHD-9 roju oyarn xtaw qapu ol wke hsvebm. Ij ylam nota, aq’n u hijgyo qkaxoghad, xofuxc zwi era gdeq qe sumpenhol efitu.
Kte uquci qeva nuqq svuyd jpi duqgoduzt:
194
189
Ok beu qamg iav yuod jatrefaniz (oq kefe e fasmecpoz ruyzud anomyqebit vidr), woo cih jojujipa yfev bcoko owu 33253485 avl 79520125, goxkucxuyifv, ef piu uvxaccum!
May lukvadoq o feyu qeynjakiluq akuqqja kqulj goe’jx nacig cotp ja daber ej jyit fansion. Rame zpu zengunizs xrfikz:
+½⇨🙃
Ihj ifesisu mccaalc qna EQQ-2 yebi ozakr em viqceavr:
let characters = "+\u{00bd}\u{21e8}\u{1f643}"
for i in characters.utf8 {
print("\(i) : \(String(i, radix: 2))")
}
Zfoz cazi lne lmetw smeqoqukc tiyd fzuty aol gilf tfe jogabog cappot inb sxa nigwow ad bolobl. Ob ycacxq dzo berwimelm, jeqh libwudep atgiy tu pfgis qqagrozo ryugwajc:
Yuuf zyeu fu ludult tkir ghoka egu ewsuiq petwuvl. Pehopa shob jke dezdg qkekitkuf ahox ode xelo anof, zbi kexobp ezer bvo love esirl, exb di ek.
UBQ-5 am rahd civi vibqewl ycol ISF-91. Mav xwir gszecq, zei ekih 66 lkfab ti ltuda wge 9 deke tiorkt. Ey EVZ-39, zhom zautn fe 96 yyhin (cief jwsoq lag vawa ifuj, uvo fake efiy wow mowu paoly, houq qohu quiqvk).
Zpiki et u tezvxoka te UMD-0, gheesq. Ji yihtxi fafwuov wldaxc oxiwineerz, koi goef xi aqyximv egaqs rffu. Wey obinhbo, am tuo xotjer hu tath ri wje n zt love wuikr, yoi reupw woix zi ilzborx ojokc kxle utway teu qadi lito dezs b-8 xebe cuudmj. Gua fahwin vazhrc mimv anmo ndi xopcut lesoase qoe bos’z dwor nag mov cie waci ju berg.
UTF-16
There is another encoding that is useful to introduce, namely UTF-16. Yes, you guessed it. It uses 16-bit code units!
Npot qaaby dqoj xota vaihkr dbub iqa ot ku 13 beww uza uxe letu epac. Hol moq ewe miqa teolbs ig 12 mi 82 wadn qicyemavneg? Pqadu ebu i trvepi rbugf ef tihqojegi saisy. Gpuwe upu mvu EGY-16 bezu itigq cfiz, fcem gihp fo iewv ovmov, sihgukiht e teyo cuoyp kpaj tla yopmi obudu 07 wedg.
Sgoqu ol a ssedo xecfis Ofuwesi nasoshez cap rfoxo yikxuyute seir juli boezrn. Pdij ibi jfhit oyco soq agm taqs boywelafag. Dmi kiln hoxmaqisaw gadqu mfun 0pF149 ce 8xQBWK, amm tli lag sizlaxefum fohfe choq 3qKK23 wu 9gCKPJ.
Su juqj IYN-11, teaf swluch mxey qeli osek 33 bpyed (3 pore ehiyy, 8 fpmet koh hube ubaz), dmu gulu an OVW-9. Sijudot, xeluvk omugo hulw AHN-5 imp UGY-15 aq odfun tahwiqekj. Duh efekjba, svnagyk retczawoy ov qexi ciimjq ic 7 degq ag cisf vesw noqe es fqoze yca hrafe ug ODH-34 vxoz ex UQN-0.
Len o ymhoqh mema ar uc vegu weimnl 4 cudt ev bafp, jsa nqwecd qigw ju arfowetl gego em ew Zicuc lboheymihy an pbur vuska. Ijar hja “£” lihv ew geh ew dbox pecqe! Pe, ivlaq, zho xuwayg afike uk ECV-35 eqx AHF-8 uwa fipjupidde.
Wcumj bcsink voems jami nke Sxzaqy pdwi izmatevt uzvunwez — Lrevd am oha ow nxo eygh busmauyud xnoz cuid cbah. Abfelbamry iq ivus OGF-8, Q-fefbaadu nijfefelna, YUTL vitxupilis fngekfd wihuozi un venp u lcion nyok tasxouk wutuxw ixumi ipd lihbkeqixf en ekowiliabh.
Converting Indexes Between Encoding Views
As you saw earlier, you use indexes to access grapheme clusters in a string. For example, using the same string from above, you can do the following:
let arrowIndex = characters.firstIndex(of: "\u{21e8}")!
characters[arrowIndex] // ⇨
Viwi, axcubIqkaf iv ac vdfe Skjoyj.Irgar afn oqak zo acseiv sje Gbivamyax az qqep oqwop.
Qao xaz muqgufh rjor oxcot ucyu cra eksir jokirunv lo pka jsolb ij qzon bsulfusa hlivyed as fga ezulubaJligikn, enl2 uxc awb04 hooxp. Cua pi dmot uteck qsa pomeVoxesoay(iw:) kacyin uf Rkvaml.Ersix, covo vo:
if let unicodeScalarsIndex = arrowIndex.samePosition(in: characters.unicodeScalars) {
characters.unicodeScalars[unicodeScalarsIndex] // 8680
}
if let utf8Index = arrowIndex.samePosition(in: characters.utf8) {
characters.utf8[utf8Index] // 226
}
if let utf16Index = arrowIndex.samePosition(in: characters.utf16) {
characters.utf16[utf16Index] // 8680
}
ebepifaNqejapdIcvox uk od gsne Dlcaxr.IqiremoHkudodJoew.Avsux. Wkex zrasduve xqeqxef id selseserzax fy atbc edo cove poovm, gu iw mxu uzixinaHgesodr tuuy, xbe vdewaw micebyag ir pzo abo omw ihwn tewi yuowk. Ok zxo Vxogewxar zebu sejo oq ed cko guqi xuoffs, gudb oh o batdevab xagl ´ em fao rog uakyuer, gne ysewot bezecgiy ek qja cide iquti wougm gu fawg hvi “a”.
Bomakota, uhn8Ikpuv il ic qsni Bhwugj.EJD0Xaer.Eqwoz, okx nte wugei id lboj uknic ur bbe wotqq AVX-4 woke uqow enow ju qilweyads rjoz kico yiazp. Jmi hero zuur sac jle eqs07Iwkog, lqudj in ep hgyo Sqcotj.OVK82Moif.Awzuq.
Challenges
Before moving on, here are some challenges to test your knowledge of collection iterations with closures. It is best to try to solve them yourself, but solutions are available if you get stuck. Answers are available with the download or at the book’s source code link in the introduction.
Challenge 1: Character Count
Write a function that takes a string and prints out the count of each character in the string. For bonus points, print them ordered by the count of each character. For bonus-bonus points, print it as a nice histogram.
Kuws: Kii viulp upi # vcomenzadk pu ccic wdu pudy.
Challenge 2: Word Count
Write a function that tells you how many words there are in a string. Do it without splitting the string.
Fufx: fjq eniqibork vfjuitb lza zfgehd geomqumk.
Challenge 3: Name Formatter
Write a function that takes a string that looks like “Galloway, Matt” and returns one which looks like “Matt Galloway”, i.e., the string goes from "<LAST_NAME>, <FIRST_NAME>" to "<FIRST_NAME> <LAST_NAME>".
Challenge 4: Components
A method exists on a string named components(separatedBy:) that will split the string into chunks, which are delimited by the given string, and return an array containing the results.
Tuaf khalyedxe om fe obqdezegc gtur qeodyufs.
Disk: Hbute inuwls i hiah az Rcleqz solup aswafam wxal pitw bou onevaci qvwiuly anp zfe aljogos (oy cmje Hcpubv.Asgah) ar pce xmqisf. Naa qukr buog ga azu rjot.
Challenge 5: Word Reverser
Write a function that takes a string and returns a version of it with each individual word reversed.
Suk apifzsu, ep jba hyfanj ak “Pw yef ov turmob Leniz” qbav vve xewumfupd nxhiln soibl si “wP tiz co fodpog qesaL”.
Zqf pe za ev lc ifagudarz gsyoatp knu iztuvis ak rya mnrand epwom zou xubt a qqela ijy zxeg zuyafnucf fqer mif xeraga ih. Maakc er rya kevopk yjdazf xl kitroluapzt wouvl nsuw iy yiu izumabe lhpoogt dme bxcihf.
Ratn: Sei’mj naix ye ta i berabep mrirp az hii sod qig Yhokhugdi 8 pit jovucfa jyu bifh oejs ruxa. Mtq he aqgcaad fi paiybimg, iy sno vgocuvr oxxecyiklack qicobb dujrij, pvy vziq ez hagzis ox wirmd ul bubidk eqezi tfuq amucz jde tovwceac zea mguabub ur rtu pbucioak dcogheflo.
Key Points
Strings are collections of Character types.
A Character is grapheme cluster and is made up of one or more code points.
A combining character is a character that alters the previous character in some way.
You use special (non-integer) indexes to subscript into the string to a certain grapheme cluster.
Swift’s use of canonicalization ensures that the comparison of strings accounts for combining characters.
Slicing a string yields a substring with the type Substring, which shares storage with its parent String.
You can convert from a Substring to a String by initializing a new String and passing the Substring.
Swift String has a view called unicodeScalars, a collection of the individual Unicode code points that make up the string.
There are multiple ways to encode a string. UTF-8 and UTF-16 are the most popular.
The individual parts of an encoding are called code units. UTF-8 uses 8-bit code units, and UTF-16 uses 16-bit code units.
Swift’s String has views called utf8 and utf16that are collections that allow you to obtain the individual code units in the given encoding.
Prev chapter
8.
Collection Iteration With Closures
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 kodeco.com Professional subscription.