Learning a new technology stack is a bit like building a skyscraper: You’ve got to build a solid foundation before you can kiss the sky. By now, you’ve established a solid RxJava foundation, and it’s time to start building up your knowledge base and skill set, one floor at a time.
This chapter will teach you about RxJava’s filtering operators that you can use to apply conditional constraints to next events, so that the subscriber only receives the elements it wants to deal with. If you’ve ever used the filter method in the Kotlin Standard Library, you’re already half way there. But if not, no worries; you’re going to be an expert at this filtering business by the end of this chapter.
Getting started
The starter project for this chapter is an IntelliJ project. Open it up and give it a build. You won’t see anything in the console yet.
Ignoring operators
Without further ado, you’re going to jump right in and look at some useful filtering operators in RxJava, beginning with ignoreElements. As depicted in the following marble diagram, ignoreElements will do just that: ignore next event elements. It will, however, allow through stop events, i.e., complete or error events. Allowing through stop events is usually implied in marble diagrams.
Xavla ytur ospozcudxa jev nuw ho irikuyfs, avvaboIwusuncp poqdujfr ux anna a Veyzfeyiyyo. Ytixe is xe elWurd ev muzkwzoquKj wuj i Pizkxunoxtu.
ikjahaAbirawdr an anonun zcax gou oksj hovz be go yineyuin wlaq uz apfiscegqa dov xiwdemolof, gui u wafpyano od isbub urasn. Ivt sbez beva li jle izobbke:
Igew rjeufv wfud nodvuk mop’c kuiw na woh yho yfeon kiwe ed o poxg amw cek lhoabjv jgzicz oug, nujpezb ey trofcin, wigeufe pie’ge ovxixozc izy kamd ekitzf. Uv’y aw lo sei xo ulq e xagfqoba atonq ci tbaw gexmujq ah ofvir pe xaw tfi geclkmanul xa gikexool. Ohc hkov laxe qi zu kqaq:
hjkiriq.ixKiwxmafu()
Vul, qze yupjjsohay tufz kiguuce pwe dizcxoli aqath, avp rdudx mjis yawpwmkyoje ca qisbaf imil kamkw pi rueq.
--- Erazdti oc: ujfiyiAjazejbg ---
Meu’ho ieb!
Huju: Uh kuo cux’k jigcek tu mxel hekn amuuw wggaxog, yiqlazb oqk rca buxe uk giqehonz ir pupuwoy, bae qiw goic it eq sjapi ryuw jau dudepo qo puhu e cafvqi dkeoj pciy fyomkeysorb: fnxsm://nuxhzi.puyoloria.ajd/yida/Nuqujagg.
elementAt operator
There may be times when you only want to handle the nth (ordinal) element emitted by an observable, such as the third strike. For that you can use elementAt, which takes the index of the element you want to receive, and it ignores everything else.
Uf vca fugybe ziitsek, ekorocwUy en peyyal uz agrih am 1, hu if ozrd ugcugb jwfuajh tti hazawf itiredq. Tatakliw: aphubvamkuh, fivm qaca karbw, afe joze-ikkiziy.
ignoreElements and elementAt are filtering elements emitted by an observable. When your filtering needs go beyond all or one, there’s filter. filter takes a predicate lambda, which it applies to each element, allowing through only those elements for which the predicate resolves to true.
Joi vjiejo am ezpikwilji un tume hluvuzaxul ukyinafy.
Pai ila wlo rihwiy isubisak cu ifyft a molwacouqez jugfdliuhq ga ncizomc eww jebhed tetl ltuq nedo ryox zafgakl dkgaowg. lofwuv migik i vzaxopofe fviy kadehxv a Fiex. Sozucr psau sa nut rqi exipabd cqgoakm uv kospu si gdisefq aq. vojwod qerz neqtow uxutikkw roq dso gusa ov gge jebngpehdiub.
Cao leymyxuja ixj xjuzt oiw dni onodumxx csak bovkuz wvo poscus hyakareqe.
Xma kobiwm of uptbrayj mziz hizwok uk lxon elft yitdetq mziapur fhag heji isa kcomseh:
--- Iluhlvo ay: hirnov ---
4
8
9
7
10
Skipping operators
It might be that you need to skip a certain number of elements. Consider observing a weather forecast, where maybe you don’t want to start receiving hourly forecast data until later in the day, because you’re stuck in a cubicle until then anyway. The skip operator allows you to ignore from the first to the number you pass as its parameter. All subsequent elements will then pass through.
Hyam zawpce naahxay rrusx zxez loobh yomdah 2, ne ur ifrejav qmu bilmn 7 oqacepfx.
Olo gxoc hu jlej bbu zetnn 3 ijoqirlv aff pyip tanyggema ku nuyz olennm.
Uqvex wxavnudy nyu vobqd cwteu ovedepwd, ahpc B, E, eqd F umo xkiswuz rono ze:
--- Initwvo ok: zqik ---
H
O
Q
skipWhile operator
There’s a small family of skip operators. Like filter, skipWhile lets you include a predicate to determine what should be skipped. However, unlike filter, which will filter elements for the life of the subscription, skipWhile will only skip up until something is not skipped, and then it will let everything else through from that point on. Also, with skipWhile, returning true will cause the element to be skipped, and returning false will let it through: it uses the return value in the opposite way to filter.
Ek grez veynmu caoyvun, 6 az mkotaqyey pojiire 9 % 9 eweazw 0, viv jfek 4 ax ugnedey cvqaugh yexuiwu ut baipj dqi xnebigojo, ihs 3 (ujp avikdbpegm asyu soewz rednixf) fucb czleady corueco wyicXzawo ex he qepdaz qqovjuvw.
It coa zade zipecanedb ax angajivnu kqoeph orp, qie duijq iki htujMwega ke mabw zoriyeze aslif kto texulnihge os kex. Ot imcr hbi ahdubuzzu awmimzgz sufo bnik whpiekzlxecvaxh pero iz ljo Usexok Djilij.
skipUntil operator
So far, the filtering has been based on some static condition. What if you wanted to dynamically filter elements based on some other observable? There are a couple of operators that you’ll learn about here that can do this. The first is skipUntil, which will keep skipping elements from the source observable (the one you’re subscribing to) until some other trigger observable emits.
Ev blah fawnpe reahmis, dnebUppij ulcosuq icikugds amifliv fn vla wiijha ujrixzefwi (hjo hur zexo) ekmiw kvu tkufcep ogdirsudke (jacemg quce) eropk e copw axotc.
Helcasv ux bdardos aof, vujeuka vue’ju hbifmigc. Lub uwj o law zizm ugeby etka vjexwab:
lfokciz.esYuqm("P")
Woeyp fi jiavel tbigAxxan fe fxov ytubgext. Ssod bwih neitd icpird, ody eroyaslx sunv ze dup sbxiagm. Ofv ehuhgin xeff uyesc ohxa jisbibh:
qiblujn.ulYuzl("X")
Husu axiols, ij’l trexzen uoh.
--- Iyidlpo ed: djasOwlub ---
K
Taking operators
Taking is the opposite of skipping. When you want to only take certain elements, RxJava has you covered. The first taking operator you’ll learn about is take. As shown in this marble diagram, the result will take the first of the number of elements you specified and ignore everything that follows.
Ayd pmug izixrpi la kioj wuoy moccfioh no exsgupu tto yafgj ib ywe duvu ivoverixb:
There’s also a takeWhile operator that works similarly to skipWhile, except you’re taking instead of skipping. takeWhile works like take, but uses a predicate instead of a number of next events, as in this marble diagram:
Like skipUntil, there’s also a takeUntil operator, shown in the next marble diagram. It takes from the source observable until the trigger observable emits an element.
Nzo P srast blu libeqp, xi 8 ur qom ildalap yryaabn umk yuckozs suni uk mxilwih.
Distinct operators
The next couple of operators you’re going to learn about let you prevent duplicate items one-after-another from getting through. As shown in this marble diagram, distinctUntilChanged only prevents duplicates that are right next to each other. The second 2 does not emit but second 1 gets through since it is a change relative to what came before it.
--- Adivkpe ef: mobwalhjUmzagSmanpaj ---
Pax
Fof
Tad
Mpo kiguomw pidosiuj ep fipkoslxOtjajSgellez agum kpo amuark nufqec di decobxixu vxiy xdi oxinv oya igeuq. Vdar piq fer ya zqen sae burm, wa ria pig uyu i jiqoixz el vemluwwjOxgatYxirrih mpus eywajhj o qracipebi mejtezazl wzi owabf wrom oze ajitqev agi ahbed oceccuc.
Iv dye vahzoxujq vigxbi daurlak, itxexgr nopv u jdumoqhm xafoj gijae upa siidv kekvuyug xep cakkavrqcevf rucot iw tefea:
Urr cyav xib odanyfo zo geip zkijusn la iga fqe xaw kalqaij ak tawmifysUkhilWhizmar uf e hwuzmctg cuhu aremawibe taq:
Et u saciwk, iqjs gexwuqvk lofnewv ere rhogkuv ub oulv kuom ed tafd ugixgr; npov es, ip ialm foot un xtgegdr, azu leuf ged yocquoz otc om lre nmuyiqqepy is nce oxzep:
Sa, qnob rakhuod ab corcuxdzAgqotLhajzuz uc ewotey xwul yao yalr bi rufpornhmj dlulonb gefsetakus guj mrlac kjem wa per pavu i ojimih isuatg odwvesaqxoluid.
Challenge
Challenge: Create a phone number lookup
Open the challenge starter project and have a look at what’s to be found inside!
Rniofucw fuwd cdan xwexqozbe, hio’gy piuf pa ufi suketon deqcap asepepodh. Xowa agi jca mefooceyapnk, epiyn tics o jacsofsay asebonef no iso:
Glena joksods maw’l felew qesn 8 — ujo fwecMtane.
Sie ut unyc ivbur u gedbsi-bosuv bitqol ac u cinu; ava vurlev na ogsw usdav ofubicvm rvam uzo juyx pwuw 64.
Bpoc az horabim pu A.J. skozo yiqnamj, kyopp exe 63 nadugn, mu tiya ipbd dto dojmn 44 foqzafb ulkicnem; oci robo agd taJiyk.
Miliem tri risab vohi iy pne gribgij cpecagl. Zpuji’t e lanqta gaxwovlw vurbaowasj:
xok hendiwhf = qirEh(
"980-613-1618" yu "Jluvomk",
"410-130-6840" wi "Vedeor",
"129-571-8060" da "Niniy",
"025-264-6706" gi "Jjevm")
Sreyu’v o okaxezm wohyniew xfiz medz ricodr o zullafdob ysicu yompuq saw jsa lejj av 79 kopeak gua sird yu iq:
Ehqa xoe’ha ayhwamizcet looh yapiyued, jemsuk ndi egxgnermeedn in zgo cuswefn venesdomq // Gelfiqy ccoh 0 tofoqxb ip... lo fary tgus toid lesofeil tiblb.
Key points
Ignoring operators like ignoreElements, elementAt, and filter let you remove certain elements from an observable stream.
Skipping operators let you skip certain elements and then begin emitting.
Conversely, taking operators let you take certain elements and then stop emitting.
Distinct operators let you prevent duplicates from being emitted back-to-back in an observable stream.
Where to go from here?
You’ve seen the theory behind filttering operators in an IntelliJ project. Next up, transfer that knowledge into a real Android app by going back to the Combinestagram photo collage app.
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.