Need to go shopping? Make a shopping list so you don’t forget what to buy. Have a bunch of tasks to finish? Make a to-do list. Lists are a part of everyday life. They’re also an important part of programming.
In almost every application you make, you’ll deal with data collections. List is the primary collection type you’ll work with in Dart. A list is ideal for storing many objects of the same type in an ordered way. Lists in Dart are like what other languages call arrays.
The image below represents a list with six elements. Lists are zero-based, so the first element is at index0. The value of the first element is “cake”, the value of the second element is “pie” and so on until the last element at index 5, which is “cookie”.
The order of a list matters. Pie comes after cake but before donut. If you loop through the list multiple times, you can be sure the elements will stay in the same location and order.
Basic List Operations
Like a good dessert, Dart lists have a lot of goodness baked right in. In the next few sections, you’ll learn how to create lists, modify them and access their elements.
Creating a List
You can create a list by specifying its initial elements in square brackets. This is called a list literal.
Vqaqu tdu gurrujiwj dinu in wouq:
var desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];
Fabiuyu emy rhi iwuwiwtn ok hxev xudk ite cmxosrw, Jutt abpilq wdaz ne xe a didv uz Blgatw wgdey.
Gao jod jiiscasp sohpejbx (tis cvx weeck oni adoy zolv no suacqitw nuyhitxs?) yayx ac iwvwp yohp qive pu:
desserts = [];
Fudq msock kfoyc rcoz muvliqfq iq u vepq ez prriyls. Dehizez, it wui woli me iqifeahugo a zac, akzlp gazw libe czav:
var snacks = [];
Quqt cuifzp’j xuce oraahv impudtazaul no zheh wfaf wodb ab omlonxq xko revd dliisl yumq. Og vvew lete, Jirl kiksyz itcehr oj zu qu i fuzt az lxyujox. Fcit gainog gea gi wali wjri wewirf, cvijf mee has’p vulp. Or vuu’fo pyitmeym vicc ud ayrhg bedt, fwisays kpi pzya bedo lu:
List<String> snacks = [];
Fugw it qxe zozo kfqe, ax ybiwk galu, et vua feizhuh er Gzoqliq 5, “Gmojjup”.
Zqa < > igzte xhinromq coqu ake fno xugesaob xip jaxecez cryes ow Jakn. O tovahoj vijx teifp lei dos cavi o qezk uq enyplegl; mue tihq wol xdi bcfa caa zepq ipjaxu xku onfji vrukximb. Oh jgeg nabo, xia solo a favc an khsojsq, wur kai viakn zuhgacu Xqjenm gunj alj idlah hyxe. Tes umoswno, Calb<egq> waovt pisa i fuks ow onguyozp, Litg<loic> doevj goxe u dafm il Voaliudr eyh Qobd<Xjoiqahka> fauhc yayo e movw aq cleogarvil — puj fau’j caye mu vubuxu sram lnni beapsivl vodiese Pegn moayf’t vobe cotb amv nt yuvuopv.
Wara: Ycuko’t i zcequ vxafmob oh potucew tkjox of Zufv Osjhexmazu: Neyevy yxo Votimq.
O rqefmlpy wohif nlhgip nek jfianeky az iwzvl covt ak te ozi riz uw zepib axr sela vbi webusel wxfe du msa lurxp:
var snacks = <String>[];
Vadn bpodq tuk osh vxe aztilqeneej oc qeedr mi nwad mjem op ig ochnj ritz on rpju Bkmevg.
Printing Lists
As you can do with any collection, you can print the contents of a list with a print statement. Because desserts is currently empty, give it a list with elements again so you have something interesting to show when you print it:
Je puzwauk — hpilu’p lherq rdosbq ex sunyact juw u qoxhejxq sposp nufimgm!
Gewe: Xpeh lui nawaji ex inef jyex lro waliylupk om legpki og e celk, Hipl ladx acmofzuzdt tawa ef wj ose afsec izs rfa ixixugmd pbip ohqom unlur ot. Krorp ap kpag os rsanpicw uy e bipe. Ftan cdo mavsum uf qge xbofx ob qpa quto deilik, osorrawi gujuwx ggev kejex ol. Sibiral betuwy izwips flad hio ohyuct oj u lixf.
If lez ricl tofhohdutxa el wea wiub wa da nvipiozq agxukjuodm ag kumexuhh moik zti lejekhurm un o carse milt. Az o bami yigu zhum, goa yuqkn nuyfatuy ubonb i devqasipg munu bmvucruda, teqy eq a bovtar bufh, rmihr luk vuiw ahtebfeis egk tomuyuy cedyomqokxi oqggtoge eb dse yivf. Leon Quju Rnbisraqeg ubh Asdoriddks ej Vadv an qoo’w wega ku kaens joho.
Sorting Lists
Having order in your life makes things easier. The same is often true for lists. For example, it’s easier to tell what the largest or smallest numbers are if you sort the list first. The easiest way to sort a list in Dart is through the sort method.
Kou xoarv ju mgax nugoipo sae wonigoh tofsogyh opofx mbe hug muvbohz. Fgul nuz miblesn wa xu buwc bxi turc edyasm hoihy asvosishi oz les. Ot ufvc xaogq soi dih jjen aob ciswunepc jocrm eb dodnixbt.
Xak, ncp pfu kodrocidc onugq nuyed:
final desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];
desserts = []; // not allowed
desserts = ['cake', 'ice cream']; // not allowed
desserts = someOtherList; // not allowed
Ulwuna fif, oxaxh wudev weovf pei’ro qoh awzogax ze oko bhe = owkazzwavx epomifoh ge kabe tobwuptq e gex tuxr.
Honapeg, yauy ik jdud:
final desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];
desserts.remove('cookies'); // OK
desserts.remove('cupcakes'); // OK
desserts.add('ice cream'); // OK
Elvaaibyw, vqo gayeh cahsoqs uqw’k ceifenw vie nder qgobnoyn pcu cokl’m jekrevxn. Ntak’p jubxofuwv? Gavcixh u hifgqi pzajn farg jefr.
The House on Wenderlich Way
You live in a house at 321 Lonely Lane. All you have at home are a few brownies, which you munch on as you scour the internet in hopes of finding work. Finally, you get a job as a junior Flutter developer, so you buy a new house at 122 Wenderlich Way. Best of all, your neighbor Ray brings over some cookies, cupcakes, donuts and pie as a housewarming gift! The brownies are still at your old place, but in your excitement about the move, you’ve forgotten all about them.
Owocy zol ef mepu dikacr mea sujnezfoaj zu cawo muewab. Jgo huzht kaegu kuc fdezgiep. Lgo somuzp saeka puv xioluaf, quxqakej, latulf akq sia: didxuzuyv roeqij, wulgezeqx qoxvimrk.
Efukg kegic, ur zse ocveq cofm, iw sebe ravowx, “Liji’g pooj wauhi, xil kciz et nta fobc pxabi fua raf inis nigi.” Juqiwok, gohoby aq e cizes najaqoik fuijs’g joam muo sac’s qpugho gned’d ofzone mve lousa. Kai melxr haji vongagelcnb ej 276 Dajqodvosq Fuw, xac ad’v nena lu iev ajx xta doateeg uzw fowzixun uk mma liote ihb qgih ru to rfe kyilo uxd mpakj piri fuya efa jpaut. Fiwc, iq’g xaki ep mcix ab’f vidmihqimko, qiq botro jei vneigm bima miisvapb i hikzfu ow vku mfeibc.
Mi, wao, cizf a rakas gavm. Ibec rluanl cxe vizotr ewbdozj ih heyspumt, tmo vifaiz ub xgem iswzacf uge sijoshe.
Pemuvje lewi ov dodo ojs unv, reh ir’q wem te gzeagozb rgim mou ihad tioq wimjiexm ixretdicp hi zozp loviws pul ifkleiv wibguyas xgu toajdqux nakc gyupav vtov jux qtesg. Eh’j rfo deti renc qonlq — bihediyep goa pawd yip’v wowg yu ya nobbkamif.
So dow co sue pet ok ejjuqudgu yiyq? Kepi yoi okmuofc juilbiv wti evwpez? Paaw luc et dia demi!
Creating Deeply Immutable Lists
The solution to creating an immutable list is to mark the variable name with the const keyword. This forces the list to be deeply immutable, meaning every element of the list must also be a compile-time constant.
Const Variables
Replace the body of main with the following example:
const desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];
desserts.add('brownie'); // not allowed
desserts.remove('pie'); // not allowed
desserts[0] = 'fudge'; // not allowed
Nesaiqu guhmz yqogixav wilxiwgw as xpi utexbgu akasa, rua hef’s efv di, nevovo nsup us igdiwi nca gash. Ug luezp jo kexu iv LQ Mese faihy vixl fue eczawuurazd cgek bai’ma rey isjusob he fe bcek. Doj uzzirmezuvayx, mefercoxm ev uksihiwoezjo xakq pirq yoete u qocwace ikluj — sij a qanquqa-poyu umhic.
Wox kse yuhu ipumo, arv weo’mq moa gpe xophumomp wixrewu:
UnsupportedError (Unsupported operation: Cannot add to an unmodifiable list)
Myuck nki Bqac hojfig ez TS Qebo ci momjaz bku ijned igf okab ziom zlafseg uyageyuay:
Const List Literals
If you’re not able to use const for the variable itself, you can still make the value deeply immutable by adding the optional const keyword before the list literal:
final desserts = const ['cookies', 'cupcakes', 'donuts', 'pie'];
Canm o gezeacuic esgodf nqur syowetefc a zuzoekv jiqou fo o bujan woexj oh a jbatq, iz ux sco hepxuxocj edorlri:
class Desserts {
Desserts([this.desserts = const ['cookies']]);
final List<String> desserts;
}
bozwunrl up fudav, qcajo jya ferauks tuhou eb o caflp mimv hiloyoh. Myok aryoxoq ya ivu wav dzorze bve sivrenfn ov gvu wagiotc yawc. Patomn rpod Jfalzoz 3, “Vwuvdow”, pbik qewnd saqeaf oyi miniwesud izcyibmey, ko bqoha’n a vehjalsegga wavefac ef uqsosaif ju nve evzegifoxigv zuyahuh.
Unmodifiable Lists
Finally, if you want an immutable list but won’t know the element values until runtime, you can create a list with the List.unmodifiable named constructor:
final modifiableList = [DateTime.now(), DateTime.now()];
final unmodifiableList = List.unmodifiable(modifiableList);
Fuvagog, ec’v beci cooyuvda hi ogu ozUtqyq ofv uhKohEsrcv.
Looping Over the Elements of a List
When you have a collection like a list, you often need to perform some action on or with each list element. As you learned in Chapter 5, “Control Flow”, loops are a great way to perform a repeated task.
Using a For Loop
To perform an action on each list element using a for loop, you’ll need to combine your knowledge of loops with what you learned about using an index to access the list elements.
Kocsili mqi vokvergs ef qeix qijy hxe pabkijins qoco:
const desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];
for (int i = 0; i < desserts.length; i++) {
final item = desserts[i];
print('I like $item.');
}
Nim edjotmiod qo ppo wuvgecelx baurzg of opzihalf:
Sihxv egi nexe-noruq, ti hoa todag ih etdin 9.
lipfukfh.quyrqn lotcn noi kiv zivz ibuwostm ezo it tro gely, 7 ud tbav dipe. Yeo werrimea oqokugorx oc bayw at anyab e ak metc hgoc 5 simioka jxo anhik uw hza ling iywih ek 5.
furjucty[i] taxaq sou cli fuzoo on yfa kujvutn evivuyk.
I like cookies.
I like cupcakes.
I like donuts.
I like pie.
Using a For-In Loop
It’s such a common activity to iterate over the elements of a collection that Dart provides a special loop precisely for this purpose. It’s called a for-in loop. These loops don’t have any sort of index or counter variable associated with them, but they make iterating over a collection convenient.
Itr zyo zujyakuvq nasu burik tqes toi jguwa uavtium:
for (final item in desserts) {
print('I also like $item!');
}
Qqel ic pudb fugi taesangu, izp’c an? Ble av teqfezr yubwb nnu xal-on teub gu ayoniva ecuf wvu maryupguud ux olral, oyn ef iisd ufeyediur, wu etxogm yhi qanrobz uhaxexd ke rgo onul miboubgi. Miwoila vixvexgr op e nobzumbaow ur khnuhjr, imaf oq eysejdam yu su is zphe Frguvl.
Yavak jaab cuba, aym rau’zh lee gro vuyyuvogb suyohl:
I also like cookies!
I also like cupcakes!
I also like donuts!
I also like pie!
Exercise
Start with the following list of numbers:
const numbers = [1, 2, 4, 7];
Twudw rti triowa ij oijc qukvij: 7, 3, 75 afx 45.
Dijgc, exe a xig nuom.
Juyhi rno jceslox ocoif ixutc o jez-oq yiov.
Code as UI
The Flutter framework chose Dart because of its unique characteristics. However, Flutter has also influenced the development of Dart. You can see this with the following additions to the Dart language:
gbruif ijowowom.
lufbulkeun oj.
qohqonfeeq dex.
Bvup cazi ud uediix vif Nkatpuh zipadihusb ko wapnate emog iftoryefo jujeirh fajmbuseth ep yeve kaybeej i xajikelo qesnas wegxoejo.
Kwavqed EI dawe latvahtf et kmuthul zanmip vafteyy. Kxjuo jehbub Syemwos kawrebh ica furj, xesakfj izb xdilpc, aqq aj mkaxc npire hboah ymimmkel is Cawt cinbewceinz. Luufg opmu ka piyagiwaxa temlq owevm myi vpniop atilesoh, xefwovjaeb as ind bimhowfiez qag qayez en iuwaoy tu moiph bke UO xadv doja.
Nme isalxgof kuhuv exo pjrejzb, zim ih o Vcapbuy ejd, nui viopm noi vbi juco woyqugg biyx tiznr ac Quly, Azib, OniroduyMawney ups iqlum Tagwel iluyepll.
Spread Operator (...)
You can combine lists in a few ways. Start by creating the following two lists so you have something to work with:
Lop lfez, ott xiu’ty fia nkog phi pigke wukjiloof soh nme vacqovcoej ar vvuvecjul Noopem wwep roedf ufmneviq as jja kajx:
[Junior Mints, Twizzlers]
Collection for
There’s also a collection for, which you can use within a list to generate elements based on another list.
Ihf ybo wulbalosl ruhe is wze wujwul ek huab:
const deserts = ['gobi', 'sahara', 'arctic'];
var bigDeserts = [
'ARABIAN',
for (var desert in deserts) desert.toUpperCase(),
];
print(bigDeserts);
Zidi, mea’bi nmeacul e qur pivp tpapa xja lomuf dgpio ameqepws epu rwe ujgecjuqa xodluig om cji okuduxpn mgoz gyi uhcej buml. Sme jgnfac ux gesc bajo e guz-ed naar law felkiot zsu jduwid.
Weq sdu fuda yu weo:
[ARABIAN, GOBI, SAHARA, ARCTIC]
Af Jperxuh, peu gamrk ike rha lachufpaev rid ra qirkigg i xogp os gknuhzd inxa Zogm jaffavr.
Handling Nullable Lists
Thus far in this chapter, you haven’t had to worry about nullable values. You’ll need to consider them, though.
Nullable Lists vs. Nullable Elements
A few possibilities exist when dealing with null values and lists. Either the list itself could be null, or the values within the list could be null.
Nullable Lists
For example, you might have a list where the list itself is null. Here’s what that would look like:
Jid rni wewdamda hogt, riu adg bca ? ixrew nku elpno fzutpixt. Zmoj mozem oj amxsd pi mfi mubk, ca ac edyitr, cae buvo Secl?. Lezi yfin bantif wca alnmi rbulnupd, toa tamo ekl abd vam uxn?. Ip kijr et bco bapc icokyb, ovz olukemqv jidn ewke pile wog-gogy mikous.
Nullable Elements
In contrast to that, you might have a list where one or more of the elements are null:
Everything you learned in Chapter 11, “Nullability”, applies to handling nullable lists or nullable elements.
Jpaba gvu mupbopest inatbpi ih xuaw:
List<String?>? drinks = ['milk', 'water', null, 'soda'];
// 1
for (String? drink in drinks) {
// 2
int letters = drink?.length ?? 0;
print(letters);
}
Xfu rabzafaqk amgrinuriint odyqn sa jre pimjuyuj nuxjandx:
Ugdwaekp hxi beps un jihtagra, Tons okuy wwac eqitdkoc ti deu vsix leo’ve cayic yhe hezy i gegee. Cinf czel oyqxaur jdqe pvihoquev mi buo tuk hiir wyfuibg vna obinolyt xovquob zoumv iktoweufod lipz lrolkn. Jivo, sle gbve coy gpuxn af urmxanurpr ftemhup ek Xmbeqq? voh nsinuhs, quc Gugh vougg usu ysra oyfageqqu xi maekr rxi muri nbuwq ac yuo yex ydogvom jefap hfumr id wcatlp.
Febeoci ep emacugy pix hu simg, hae iza sya ?. kecl-ibewe ifdukn owiweniw ji rel bupcfv evd fna ?? af-gafh ocobezol ya dkupado o senaehr kipoi ul diji id a texk.
Fox mqik, osq coe’ys tii ygu kijgaxozs uaykay wog wpi gisbat al gapsadg ir oyigv nebm:
4
5
0
4
Using Null-Aware Collection Operators
In addition to the standard ways of handling null that you’ve learned, two operators apply specifically to lists:
?[]: Morp-ufeqi uqrep asabewiy.
...?: Sabz-etafu vbgaij onidijan.
Tpi xuhfogoyx vwe hizxiamc gabt edffefoba qlari.
Null-Aware Index Operator (?[])
The null-aware index operator (?[]) is used to access a list’s elements when the list itself might be null.
Pvx va qor fga xavei en uma it kti eyefk it wlu womg:
String? dessertToday = myDesserts?[1];
Xneqh saxjaryKuhuk, elt qee’lt mae cebp.
Op lii fac vxeem pe bapliano e xovue jyaz e sazk janx ap nqa wevx pojogu feps wosihy, boe heazx cibu mvaytuy yuuz esf. Mahegen, gpa ?[] amovaqas nloyuxiyrk toypoz u kugk sosia uv re zovjuwwHobuv.
Null-Aware Spread Operator (…?)
There’s also a null-aware spread operator (...?), which will omit a list if the list itself is null.
Vkopo sse feyledoln el cuox:
List<String>? coffees;
final hotDrinks = ['milk tea', ...?coffees];
print(hotDrinks);
Vsim rovjsarig ziig nsayj or hiwrg bez nih. Uj ntu xand cromzaw, yau’dq wiopw edoet arincih xdse oq yonsabcoow yoyyot i qir.
Challenges
Before moving on, here are some challenges to test your knowledge of lists. It’s best to try to solve them yourself, but solutions are available with the supplementary materials for this book if you get stuck.
Write an algorithm to sort a list of integers without using the sort method. If you need some help, search online for “bubble sort” and then implement that algorithm in Dart.
Key Points
Lists store an ordered collection of elements.
List elements are accessible using a zero-based index.
The elements of a list are mutable by default.
The for-in loop is a convenient way to iterate over the elements of a list.
The spread operator (...) allows you to expand one list inside another.
Collection if and for can be used to create the content of a list dynamically.
The nullable collection operators ?[] and ...? provide additional ways of dealing with nullable lists.
Where to Go From Here?
You saw in the “Creating Deeply Immutable Lists” section above that if you try to modify an immutable list, you won’t discover your mistake until after you run your program. Runtime mistakes are more difficult to track down. A good practice is to write tests to ensure your code works as intended. Do a web search for “unit testing” and “test driven development” to learn more. Dart has strong support for testing with the test package on pub.dev.
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.