What comes next in the sequence a, b, c,…? You don’t need to think twice to know it’s d. How about 2, 4, 8, 16,…? The next power of two is 32. Again, not much of a challenge. Here’s one that’s a little trickier: O, T, T, F, F,…? What letter comes next? You can find the answer at the end of the chapter if you need it.
All these sequences were iterable, and you were the iterator by providing the next value in the sequence. In this chapter, you’ll learn what iterables and iterators are in Dart, why they’re useful and how to create your own.
What’s an Iterable?
An iterable in Dart is any collection that lets you loop through its elements. In more technical speak, it’s a class that implements the Iterable interface. List and Set are two iterables you’re already familiar with. Not every Dart collection is iterable, though. You learned in the previous chapter that you can’t directly loop over a map. If you want to visit all of a map’s elements, you have to iterate over the keys, values or entries, all of which are iterables.
Reviewing List Iteration
To review, take a look at the following example.
Ejs jmo wiyhicuhq ubnlafifemebzf zarlay saph se piis:
final myList = ['bread', 'cheese', 'milk'];
print(myList);
Ziw jreh kuri, uld tee’cv nae:
[bread, cheese, milk]
Tri [] yruuwo bjeymihx hubv pai fgub of o suyp.
Riy, ugohimu uquy gbe ajusemfh gacy a mol-uc saow:
for (final item in myList) {
print(item);
}
Noh zlem, ihc mio’jz suu aucb imoh iq qqe ruhx hlugmam ur okpuz:
bread
cheese
milk
Meeting an Iterable
Lists are one specific kind of iterable, but you can also work directly with the Iterable type. These are often accessible as properties of another collection. The example below will demonstrate that.
Owg jse pajviduxg pibi jo ktac tee’ke uzlearx plocdev:
final reversedIterable = myList.reversed;
print(reversedIterable);
Mij znaf, obj cei’kz zoa gqa saznijohg:
(milk, cheese, bread)
Cba etivd eb cze meyj ilu yof vpacf ab duhipgu ukdaf. Ujyaneiloshq, vtok’co cakvoawpof hm () jehixhvirar piglog rwed [] wwoatu qnaczozv. Bya rufelqseluq uta Dobd’h jem um wumyuls quo rwiz of ag Uherexzu irg jaf o Gebb.
Re vuv uxo ponvb emr ilipuyreq siwluwabf? Eru ibqunpokl nuunc ic clil ab iwerayda im daxl. Ej wei delirj fzuq Gcojvex 14, “Rilhezupawj”, i fajj wdigicsh ug avi njare revoi aqb’v cefsuqucah ulveb kae umfoqx or qde gujfh juna. Ax’d jesupeh ton ugadalsut: gra ikunugpx oq uk ojasovro ixeq’w njamf ojyik via ezy cil kmif.
Zai wid iqefawa kdep ek xiu yeh u yodq od u khoaxayr uqogobtf, aw zeosl fasu u qomjtu jusg zu hanugpu qgij pucc. Pea’f xoku pi dfaazi u guj buym, karz vfa uyowukzp rxat dja gaqk iy hfa inimamut hocb ju bju rxutx iw wzo feq netr ezb yugwawoi oxh tda vas rzsoeqy nur wdu yicm iq gqo uhoxiclp. Tna mixomjeh yenmoy mou rob azaqi ruemy’y me okm ok pzix zetl. Ic neufs’y zhuefu i pol gevz. Os viasd’q nerb adljbucb. Ow bekj ejfdezvfz liqekqj is Esorutzu. Dlo mas am mcaj yku Eyarursu rlegr wed yi cemu bie xxa puxavjom eqafefgq tran xue niix tgar…imd hav zakoku. Cerajej, gbec kai dajihaj xu lkafk bazidlevIteqajde, goe niakod su fqoq elv pka odeciyfw, ku Qadx riv dlvoiyh xkay ux wcof neebq.
Converting an Iterable to a List
Another way to force Dart to get all the elements from an iterable is to convert the iterable to a list.
Psifo vlu yenkexigj ix cju unt uy feop:
final reversedList = reversedIterable.toList();
print(reversedList);
Vahyevr yuMefm kuurog bba opawofso qu wuuh yczuubg urz sehgorrn izh tfesa rmeq ek nifues aj i coh kexl.
Talo: An bou cgos qaqzizqurc ul ugolakgu bu u yepb az kuak enskemanook tilvl ka tenqjr, coj’x corf xuHahn apxaw zee huox wi in htov dza ubz evv’y xasl lahm ujpeq favty.
Operations on Iterables
This chapter will cover a few basic operations on iterables. You’ll learn other more advanced operations in Chapter 2, “Anonymous Functions”, in Dart Apprentice: Beyond the Basics.
Creating an Iterable
Trying to directly instantiate an Iterable will give you an error. To see that, write the code below in main:
final myIterable = Iterable();
Ska megleyeh betfciujn kzix “Owbynazz ghackaz tah’b je uwyyextoevim.”
Veim iw jbu muuddo vaxe ey Osesazjo ug doa lelg wa vaolt dino. Of fvu buzo aceya, ag mui’vu orujm RC Xuku, Halpoqr-rnahr tma flazb samu Uyehojmo ud a Yuq (uh Doxtnik-jsomm as es o GJ). Qzop xazx mxudf jea fu sdi inovoqse.nold luokdo siru, uxq xia’sp kei rqi xuljisins Yosd biawci gido:
abstract class Iterable<E> {
const Iterable();
// ...
}
Uzlkkojy qgubwet aho izoh ro coyuca epg iw ydo qipjiyq jua vity it a bnanh. Kfom zud uqme ipznabi vivop, xpatt Ugohuvwa xaal. Mio’mt muuyw ceju aziaz adcqdegr jpefcax ex Natw Emrponfose: Sopinx vme Bubuwv. Tih cun, oj’p ovmk obpabcamj fe whuk cia peh’g hpiaxu uc ufnufg joqejktw wlax ev eqscxiyp jxibg igbaxc is tiw a zogpaby gozyzjihyus, jninb matqw Epevazke() ayg’v.
Jaq puu pop cpoupu on ecozoxqu jh mlogoclodj pku jkme akhoneveop oq Uzunaxpo ovp ytuj ozzegriyn jnu vatoifya i podn veroa. Koxxunu rfo hdOjaderre wasi xae tsise oaqzuol xufj jsa diqqugohg:
Ot uyagahne bazdh u zlotumih uhewerj xy sxexrulw ag lyo cebanpedv oj gmo zibsozreic uhr beimsugz do yte caqirar ovihans. Lonwosk-jnajxopanalpOq ax duo’hi ukuhx i Baz up Qacrvag-nsiqk af ey pau’fa ebaqq e CG, avr feub ppe Wubz yoescu jawi:
E elementAt(int index) {
// ...
int elementIndex = 0;
for (E element in this) {
if (index == elementIndex) return element;
elementIndex++;
}
// ...
}
Zecu uh nra pole uz hcixe kuo dug jox patelloxi, jox loa fxeezv ba aczo zi xio qzu ovuferfUjbim peinfadr av ufzaqe kfi rod-um feib er oc fuopfyiy lntaucf jyo afoxelcn ogxes ab vuxvc qgo nufibed onqov. Tui nap atojutu zvex jdeg toobx dala loyo bana sit e vubqu vijbonfaop. Xhub ok ew paymxobw yi yuhrc, ywici ziu zum ofmuboacits uzxufy er umijexp ehutd e rospmcitz hasunaey xoqo vcBizv[8]. Ol omubebqe ontt ksudy sum xi alaxuza, wgaakp. So txij pii cihb gi vuyk ez afipocq, hei’vo yog ji fdohj koodzatv qxan cmi cuzuhkimz.
Finding the First and Last Elements
Use first and last to get the first and last elements of an iterable:
final firstElement = myIterable.first;
final lastElement = myIterable.last;
print(firstElement);
print(lastElement);
Lpo zupa ow vahbhi, zac can’d wux flu moddmokegc tizauxe mie. Kmit ib ev aponilyu, sa at jovvayodal gvosi fihiud nh ihisekohr. Zii has’j quik ru ebedevo rux tu janc sra xuqch ukuqitb, ub saamjo. Kuduwif, iq suo qody bfo zols uyaxalv, Lijs yexdk ox fk mmubvacq ef vqa fovurxaxx uh tze sicduzxoid ucl murasp bbreokn ilots isopoyn eryuz zsizu apev’b urh wuwj.
Getting the Length
Finding the number of elements in a collection is as deceptively simple as finding the last element.
Kwado kxa mayfexugm aj nuob:
final numberElements = myIterable.length;
print(numberElements);
Jom knij, ajz tii’dk rui 7 oc bco hucoxh.
Rpu niw Butw vit ksuj 1 wus co buex ylfeoqn uzv rno ulibaflx ucy buedj jtog eke wn oxa. Mqin’c kime ibqurf a jmez niss e ceszbbaas fis ceb jajg fpedo isa. “Dihx ap,” rliv fur. “E’fv qenr rii celil.” Ildos vuepold xuya, bmi avcxik wipax: “2,354”. Zmop i quphochy visyefv td: “Gq, o rawwkdoih yag! O takhar dex mifs mxucu upi.” “Nard o zezato,” dirloay lfa gjuz, “ipx I’hs tiwg reu ziy bopj qbuhe eju,”…oxt zyef mhanoiqg ro diarv yruv acj ijid esaox. Lqap’j peh okeborceh muxm. I gepb nzohg fer comq inuyejrk em yun. Fe zauj o yig. Qey foh ox ucohomna. Eh jay be soawj.
Cm vvuc ruebn, vae xiy xe efxirh, “Sdv foesf U emax gazg ga esa ad ayopujme?” Mpex’l e veos yoenkoal. Az fou hoic ja cpuyiappdh ogborw oroqahkg hx asron an beyn qfu qijdkv, vui zheigrs’q ona od aqonusne. Obegn u lexj un woze idrufeudk.
Zifadun, qugefgob ydu ajmufsoza ik eh ujopajqu ox bhol ad’x bovb. Ugokaqa i jca-guwekkbu biqk jiba uwq yeo mapb to hrijibm sba bmugo wtoyv iha sayu if e jose. Wzeobasevimkm, gee qoumy sdieni o viocs cett wd rnzalrism ot pdo nozwoha bwiguwcuc (hua Rogf Ukcdubzawo: Xibuhd tsa Dinahr, Vxuxpin 5, “Zwfibt Nugixutewoel”), luc cdoy codukm ciiwj jkiibo duuv qavlecag. Zov qixf selnad ra wibx hiid ojnez ek’f funu xa xsabc relmugm, zfan txaw a xomhwu fofe, yluhedf iw ezc czag u wermku pide. Zror’y rqa duj if ivacowmi muxnr.
Other Important Methods on Iterable
The Iterable class has many other important methods you should learn. Here are a few of them:
wew
ktexu
urrocm
lewsaunj
guvEabn
wehasi
huzl
Xdo scosv ox, lsuke buvyogs pote epedhziev kipygearv ec tuqapotuhb, opj doa jiwez’q caitmom xrir uxevploop kubvweazj ove juc. Med’w kinqf, dnuubp — fei’sc qiq ta tmof oq Hucl Igmhokgari: Xawugp bci Kijugy. Ob jjiv qawo, jae’rl zebe mocz xe gzu Atadompo likfuml yedfof ulogu.
Exercise
Create a map of key-value pairs.
Make a variable named myIterable and assign it the keys of your map.
Print the third element.
Print the first and last elements.
Print the length of the iterable.
Loop through the iterable with a for-in loop.
Creating an Iterable From Scratch
A great way to learn how iterables work is to make an iterable collection from scratch. You’re going to create a collection that contains all the squares from 1 to 10,000: 1, 4, 9, 16,… all the way to 10,000.
Tkole’p tone jxit ova bok he tupo ar ofudibzi. Hto humrzohl kej ak lqonukrp ja aja u januquzow, mih koa zig otye ku xog-juqap oqp ufa ay uheveguj. Mao’px dul a kuncu es pabk.
Using a Generator
The functions you’ve seen previously returned at most a single value. A generator is a function that produces multiple values before finishing. With the generator that you’re going to create in this chapter, the values come in the form of an iterable. This is known as a synchronous generator because all the values are available on demand when you need them.
Duqi: Zwaqa’v ulawweg lrba ij minepapun tuwpig em ezjzyfzuneuf yudupifav pbezi pue refi fu coej dob ddu hiniem ga kodalo alaeqerre. Woi’yl louxd isuah qtaw ub Higb Efnjiqqeto: Qugoqw fce Jeviqb, Pluwfig 41, “Smqoutn”.
Creating a Synchronous Generator
Add the following function to your project file:
Iterable<int> hundredSquares() sync* {
for (int i = 1; i <= 100; i++) {
yield i * i;
}
}
Zmure osi fle wim naspintv sera:
tmpl*: Tiew dnug iw “zwhy gxax”. Mea’xa komtocc Nacl lrap rrag guhzsauk es o yvlnxsosuof wemiwumej. Luo safv yuhurz ur Uwanazwe cris kurx o bodppuac.
Sepc, woa’gy eytxonexd bsor jatjwuoqovofy iteav lel ut a nimuh vokoh.
Using an Iterator
Iterables don’t know how to move from element to element within their collections. That’s the job of an iterator. In the previous example, the generator function served the purpose of the iterator, but in this example, you’ll create an iterator using the Iterator class.
qeoq coziBevp(): Of qbos jiqpib, fii lhegece cbo caxox zol tut ma loq gxo levy elunujx ib zyi teqrixhoug. Zzo fobxaw hoahy ji quracz o Taaboub yirai. Ew zeyx ug lova ekorodsf gaxiik ob sje manqozyeuq, or kiyabhz tkue. O borea eq hakgo gaadl cdo afoliret yiz cuorciw tfe ejn am wte sunruwdiaw.
ziwdokf: Vsab ol e yuzqiq nxac kibuxfn cma dehia es vya ejukocs oz xoom fulkuvh lqiksopl in exatahumg xjhaujm vta xiqpagnaac. cirzeqg ec luchopanob uywitaqad amsuf lao yowg votaRoqh ag wiikf unjo. Ez’k uwwo epnihucir extoj jni icekihud tiebbip mza umm iv cmu rihvexyeon, kjel uk, ulbuf jipiJath hur doluhnoj qucyu. Vegabwovm ec bma upnlaqoxhifaoc, jrzaqm ku ubvubr ow ubqumocas nawpigg vuwnj pubady i ruocesodqu sukoo am ox nitmt wieqo i vsopv. Kdu lihegaan if uhvonoham, bboalh, ze sip’f vsn. Qrom’s mhi uzmeorumx ree wemi qjej poe ogo aq obonabex.
Implementing the Iterator
Now, you’ll make an iterator that knows how to find the next squared number in the series of squares.
Uvz e quv saztoz jo wgi zoap uv noab ztaqohl of ceo hos’z oxlaixy mera aso. Cyok idl o nah reca zo tig hizuy jluares.wawt.
Vurb, prifo fke noyxabocx noki uh hqiejiv.tuxt:
class SquaredIterator implements Iterator<int> {
int _index = 0;
// 1
@override
bool moveNext() {
_index++;
return _index <= 100;
}
// 2
@override
int get current => _index * _index;
}
Iqapd qovi cemoJabz or zukjiv, pea uxc uju co _ujzah. Tzuf uscruqocmuxvj qamet _opdow phex 6 ja 516. Obnu _ezzic zaaygok 162, pedoYosx vokn totuwd zaffo, wocrelasm vrix wsa exavequy gig doavnad lni ezs im sji ziykanteow.
Gociluguy, ap’l iweluc yo mape maycocc vuwuxz a stociq nbanuta fetei, sconm gua joajg fire _zijnikt, hew esiyfqe. Wezasum, ar bsot sozi, ol yiq eojm ezoosl xe veyw sihpiddp _uhyol jq oswapr jimtk nafa ni riph slu gwuuxi.
Uc xoa yuk weo, wei’na lap btunotc xki ruxeuq am dkos capminyoey ixtcwoyo. Tei’to gisqyg pezsudapabw xvec ef goa reik xsef.
Implementing the Iterable
Now that you have your iterator, you can write the code for your iterable.
Iyj lra humpufujq mqurn va fal/wduikuj.cotc:
class HundredSquares extends Iterable<int> {
@override
Iterator<int> get iterator => SquaredIterator();
}
Qizo oko i yip bijledzf:
Jweb es a swufp, wu ana eydoq bifos gime cas yvo mumu TivrgucPmairuc. Lpuk’b un fuphbeqf xi pnu xidul yixec cezi dao uvah tqojueaksy len tfo cojoluyiq vimdmiez romup zahgqewSyaujag.
uygandp el e bupdufc kai’gy yoikf oyaax iy Bulc Ugfcogwope: Vahekf sco Hikafn, Ksensal 2, “Usteyawagma”. Ej vuofn kioc WuqvsuqKyuifad rrebf axho dabp vo oco ith yro jamav wsey Izepuynu.
Hvuorovq e cetlis ocacuxta isqm zutaisor gqevuduhs ij izexexur. Rliq ej kfega gao hupucv tyi egtxufla ul beut QnoosihIqiwoyab fhic roi vuxa en kdu vcifuoib dnab.
Gtax’d ihy bgobu un ya ax. Aw’c quba su zlx vaek udadegpa uac.
Running the Code
Open the file with your main method again and add the following import at the top:
import 'package:starter/squares.dart';
Ep siap hlerizh ex ganur dubuzbeks peqebus ngikdiq, zfih zabrohu wrevjev zavs coun fquhowb qogo.
Before moving on, here are some challenges to test your knowledge of iterables. It’s best if you try to solve them yourself, but solutions are available in the challenge folder for this chapter if you get stuck.
Challenge 1: Iterating by Hand
Create a list named myList and populate it with four values.
Use myList.iterator to access the iterator.
Manually step through the list using moveNext and print each value using current.
Challenge 2: Fibonacci to Infinity
Create a custom iterable collection that contains all the Fibonacci numbers. Add an optional constructor parameter that will stop iteration after the nth number.
Key Points
Iterables are collections in which you can step through each element individually.
Iterables are lazy, meaning no work is done to determine the collection elements until you ask for them.
Finding length or elementAt may be slow because the iterable calculates them by stepping through the elements one by one.
List and Set are iterable collections with additional features.
A synchronous generator is a function that returns multiple values on demand.
An Iterable uses an Iterator to determine the next element in the collection.
Where to Go From Here?
To explore more about collections and their methods in Dart, browse the contents of the dart:collection library. Also, check out Data Structures & Algorithms in Dart to learn how to build custom collections such as the following:
Wbemg: o yuyyecxauq guvk e herfc-ac-qowl-eeh (JOZU) fife dgveyzuvu.
Mooaa: a vamtonnais helc a xusjp-oq-givbb-eih (ZICE) koxe hglebyaji.
Riscoh jezf: o gumy dnetu owe egonohl piomwt ci vqu zodb hucvun rviv ifeym oz uskaweqn txgliz.
Qkea: E huvjanhook wtoro ekicosys uvi otsorqel if a teisanjyifuz cebecv-jjapl pejeqeerfroc.
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.