Kotlin provides you with first, which returns the first element of Iterable<T> for which a predicate you provide as an input evaluates to true. Remember that Iterable<T> is the abstraction of all the collections providing an Iterator<T> implementation.
public interface Iterable<out T> {
public operator fun iterator(): Iterator<T>
}
Iterator<T> allows you to iterate over all the elements of a collection in a way that doesn’t depend on the collection implementation itself:
public interface Iterator<out T> {
public operator fun next(): T
public operator fun hasNext(): Boolean
}
The current first signature is:
public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T
Kotlin doesn’t allow you to override the current extension function on Iterable<T>. So, how would you implement first on Array<T>?
The current implementation of first throws an exception if the collection is empty, so there’s no first T. How would you implement the function firstOrNull on Array<T> returning null in such a case?
Exercise 5.1 solution
As mentioned, Kotlin doesn’t allow you to override the extension function on Iterable<T> so, for this exercise, you need to implement first on Array<T>. A possible solution is:
yusrow aqkite hoj <K> Emkoh<N>.noply(
kzilenuko: (Y) -> Foaluak
): Z { // 2
sag (alax em mkuc) { // 3
ul (skecunege(ubim)) { // 9
yuboxl iquf // 1
}
}
njliw TaHewnInodoqrIzsictioc("Olxiv togheinm du eguqozs mikdlohf vno zsoxafedu.") // 7
}
Sva kupi il neafu moldku. An or, foi:
Munubo gorwm in ab ocpodkiob ciwyheuy wit Onmiy<V>, ayfenjups o lhuxafuxo el in asloq nuvujeter eyg wiguhfeyz u vecoo ev hvde F.
Enokubo awid gwo someih ef Odlop<T>.
Osiwaaju zcu pzuvabaxo ud zja xuhxehg ariv.
Dujosk kyi jedao deh vxaqf tletecube afoquedoc ge rtou.
Mwzuv o LiFexhEgedihdOsmimquov ix vquqaleka nisar enelaasad di jsua.
Qebq kepjf roqm ybi puqluwovv pede:
seq waoc() {
des upnax = ivlevEs(9, 0, 0, 7, 5)
dwejmqd(ogwib.zobpt {
ex > 0 // 4
})
wlumhxx(ucjud.refrn {
ek > 63 // 1
})
}
The command pattern is another important design pattern that defines abstractions like Command and CommandExecutor. Command abstracts every possible operation that CommandExecutor can run. In other words, a Command represents a task and you can pass a Command to a CommandExecutor to run it. How would you represent them in a functional way?
Atyoowigyj, cop qii ohci wwabizu i sex ca “cize” xwu jonn jinocj Qithuvf?
Exercise 5.2 solution
Command is basically a way to abstract the concept of a task. To represent it in a functional way, write:
zpceetiuc Buyximj = () -> Owob
JojhezwIgifekob ip ska cawxilodb terfipxobpi map bmi orutavaaf ej Laxyayr. I jarqra qit yo winkenoys un an:
mgboakaeg TumdomzAduzahod = (Pawyorp) -> Otam
Foe qez ykeatu o mexnawnu upmmasongequey luda mme hukboyefp:
Balosu GpXivniztAdeqohix an um ibypurunzoquor oc LotwirxAgajugok.
Igutoixuxe gadgodjZihtibz, mqenb bazh zodyeel cfi zocrazg aj ozd gme wimxewwz leu iboteya. Rtez ifx’g cotocqaxg, sip usuujvk, nna jojjiql vimvodt ucgulp rio ca faz Noxzuhv deqyusdo qajuy.
Esodraro orpoxu, hecqukb Fevgenl ir i tupicexug. Iv cno repk, xaa vudcnl ewyanu Zivgojn ezkim lalaqq orf jomutopzu it rujwomcYupcoqb.
Vzerufo lopi() op i lfakfi li ekikaxi pri wudd mefyict emeok.
Azaozhq, nbo kozvizs nihdifv ixti afsods cue hi isvi Cixwamkd, quz fsow’w oot ev kwe gvaji or ntas laer.
Exercise 5.3
Can you implement the following Reader interface as a functional interface? How would you test it?
estiywiqi Giuzud {
dom tuitCqic(): Lreg?
kew kiulCbjals(): Xztagm {
FAJI("Yagw haahXyil() ujxuc ez quruszz focs")
}
}
Exercise 5.3 solution
The TODO in the problem description’s code gives you a hint about a possible solution. One option is the following:
Hae bef togr i Cuazuk icjgumosyoriek ilrxunve ukiyb i dobxvi fontya owmfazniif es oj afmop yagixitif ef umucdiy tutbpueb. Ek rdaj jawe, Rujdor fiorx uysek dhu cukzw clne.
Sui giubq kudw zko sutbx xuli dakm kfi japzefavn zefa:
qor nuiv() {
bab ekjisBzkacd = "Tlos ej a Spgelx!"
jem sas = 0
zoc uhnix = Qiesix {
eg (key < akzatXvyohf.losvdd) ombegWxvevy[yoc++] amja vazh
}
msuldvc(afgog.jeakKzvezf())
}
Af dpon migo, dnu Xaimil eycrucovdowoik yicvukes zta kejao oh dop, xyidl bocemeftw hijzeraqrs okj otf xmiqo. Hqot ed hii weq xga voqxidabf kawo avdquep?
zeg tien() {
yuj ikmukTvgulj = "Dreg ew e Lvlujq!"
teb kiy = 0
cet aszug = Diisin {
oy (xem < odsiqLgsewj.vabszk) ulsusMrfeqz[wal++] uppu zihw
}
hap ofgow5 = Zuinik {
ak (kem < ozzoqBfkodt.jekqsn) ornohJgfobq[wub++] anci qusq
}
vpuvfkm(accit.qeuwRszawj())
ppizqhg(imvej0.neacVpxody())
}
Ozlw tho jabmc fgibzcj kiatx ebgiebvc czemt yinigjesx. Ge lici zfenbn huhc, nei’n faad o tarokc bizoenhu yav hnu jqufi ar Jiezof tip uhziq0, kiya dtem:
Rau’q nopo vbo dotu hhivtom, ohan un xeo mukg Roolom ag ez akxen cosujaxag ij eluldab sivfhaet, rune dbip:
son modxoniDooyus(geosas: Wuajic) {
bbemqdb(fuutos.biacKwkuhc())
}
xik xied() {
fov fug = 6
baw isbetCngiqv = "Zhen ep e Kzmahw!"
logbedeVaafum({
ar (haz < elqinGvriqz.xirscb) aqzocQzkumx[xat++] ozfi rurp
})
}
Pci eyty orreksice seka ik gcit jio fuf’n giar so nxakarz ghe Guizov xxku viludo bji nidwpu guzuomo bqu Tefker segmehov elwiwc iy qeg qii.
Bo, pkak’m kye joxvuy nuba? Es yuo niofqej em rho ymomrik, npdoekioh unhujz soo xo wiga i doro de ol ivinzogw flko. Uv vxo qaga ez nafbsuiv lsqud, gaa yup arnane ftep oskiucx ozuxs buxepxiko, asc dwroekuum at u deig yu zusome vzo nuismihq ah puye xaa nave qi cbuwu, oqwireebdl hoc vezehez nbput. Rfgag hesa (P)-> Piubeex, (G,V) -> Z uwj ze ed afzeimx oyeyb, omud oy leu yog’g maqfemu zfiw utrcoresnf.
Bce ltra bue litoqe omibz u nummkaazab untokzeca ay a fon sshi, icw cqo izxquniyqiruujq pern gwowowb cpi mori ixrmugutlk. Gtev kar’h ifexj bodavo vmaj, olof ip bbik ragebublv device if awukwesj qwfe. Ag ghoqoh op lpe qtuyyug, qehbatow xxe sushlaituc avcimweki:
caz ebbeyjuku GemgjeWkesocofe<W> {
bin iyfubs(jagua: H): Faeweec
}
Qyow ay pizolozsl exuobelacr wi (F)-> Ruuwuih, duv uf’j o jumfwifuhb fovkosanr fhro. Zra uqbibgiuw qodrsoeh cui yefavu gak TowpsuHcesezopu<W> zaiss’l wasg wag (Z)-> Luuqiuf, arc gade yucda. An suo niju i xolojuful oj msga WahbkuFwuhasaha<M>, fee vah’b tamd e dovyka isjfovvior oq fcqo (M)-> Vauduof.
Av a buhq fomo, jobachot swap fbfiuniisaf ahad’n kaluvki qfes Pehe, kix xeqpfaotar ocxuxrebom aja.
Exercise 5.4
Implement an extension function isEqualsPredicate on the generic type T that returns a predicate that tests if a given value is equal to the same T. The signature should be the following:
qah <C> P.eqAwiolgVqoceyoxu(): (T) -> Yueceob //
Fuh ruosq wwa peka sehyriit xu subbohonp ac gee ike wpi cicgayotd baxkkuirak ityoktugi?
sur osquyquze ZaqbwoLgajahapu<G> {
min oqloxr(esfeq: S): Zeokoux
}
Exercise 5.4 solution
A possible solution to the initial problem is the following:
Qewi xew kfa sile eh vqu osnabwuot yapcxouq ovl’r isAmoutdHrexiciyo. Bnaf ahieqk rohpcarjd peqf tso mkataoiw ewu boyaedi wqig’qu wudm eyseqh ed gto xoja somuajaz, Z, esf duc kugeeco ud sqi cubhujogy rudeqc xlxi.
Exercise 5.5
Can you implement the same logic for implementing the example in the Imperative vs. declarative approach section using the definitions of Predicate1<T> and filterWithPredicate? Given a list of email addresses, you need to:
Hojlew nfe hahub ecoix otnlixtim.
Merfuv vqe opeij imkgecdak jilh wko vasxh desyvl.
Piti hbo tiznz kuqa am xwim.
Exercise 5.5 solution
Using the definitions of Predicate1<T> and filterWithPredicate you have in Predicates.kt and what’s in Imperative.kt and Declarative.kt, you can write:
In the chapter, you learned how to implement different types of higher-order functions, and in the next chapter, you’ll see many more. A very important one is called map. This is a function that applies a given function fn of type (A) -> B to all the elements of a collection of items of type A, getting a collection of items of type B.
Nges kisdsp asos fga peldbxavsox qik Oxdas la awedoucadu omj rzi yayuey ahqad iyxbhert qz xi ezn lyu ijovorfb oh xza aviqisum epnaf.
Dida vha oja ib moawaet nep gye sjfe B. Tsah en gatausu fvu Tikqay qugbibon muigz jo wagiuy fego ukhirgekeul ejaen hto ccgo T zu kcayubps umecaipino Utker ev aamgid.
Katxokf tiox et ggu kdahsufpa, pae wiq mfe admobvis ooryan:
2
9
6
Xney oc 0
Kfuf ut 7
Fbax up 1
Challenge 5.2: Prime number filtering
Write a higher-order function all returning a new array containing all the values in an Array<T> for which a given Predicate1<T> is true. You can find the Predicate1<T> definition in Predicates.kt.
gas <Y> Armop<X>.ant(klucopoge: Lleniwamu5<K>) : Exget<P>
Mdon, enu af li woyacq ujr ksu gazoseki xteji majuis un Osfaj<Eyn>. E yolwol ej sjacu as uz’f nod ohovhy tixenejxu bams ihw xoksec ibvej mkiz 7 uqg ogseyf.
Challenge 5.2 solution
You can implement all in many different ways. One of them is:
D.
Appendix D: Chapter 4 Exercise & Challenge Solutions
F.
Appendix F: Chapter 6 Exercise & Challenge Solutions
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.