DEV Community

kuti Gbolahan
kuti Gbolahan

Posted on

Working with list in Dart.

A very commonly used collection in programming is an array. Dart represents arrays in the form of List objects. A List is simply an ordered group of objects. The dart:core library provides the List class that enables creation and manipulation of lists.

Lists are Iterables
An iterable provides a means to traverse items some sort of a list in a sequential fashion. Dart takes an approach similar to most other programming languages. Basically you have what is known as an iterator which keeps track of the current item in a list and allows you to move forward through the list using a 'next' method. More on Dart's Iterator can be found on the dart website however in practice you will find you are almost always working with some sort of abstraction of the iterator, not the iterator itself. There are multiple classes in the dart library that you can iterate and some you will work with more than others. List is a workhorse and you'll find it being your go-to more often than not. But it's certainly worth knowing about others such as Set, Map, and Queue.

Here is what we will cover in this article:

Creating Lists
Looping
Filtering
Mapping
Sorting

Creating Lists
There are many different ways to create a list. At times you'll know the length of your list, and at times you won't. Both approaches are easily accommodated by dart. There are even means to dynamically generate a list. Here are some common examples of creating a list of strings. I chose strings but as you can imagine, any type here would work:

void main() {

//Fix lengthed list
var namesFixed = new List(3);
namesFixed[0] = "Joe";
namesFixed[1] = "Frankie";
namesFixed[2] = "Tom";
//namesFixed[3] = "Kaboom!"; //this would be an error
log(namesFixed) ;

//Growable list
var namesGrowable = new List();
namesGrowable.add("Joe");
namesGrowable.add("Frankie");
namesGrowable.add("Tom");
namesGrowable.add("Larry");
log(namesGrowable) ;

//List initialized upfront
List names = ["Joe", "Frankie", "Tom"];
log(names);
names.add("Dave"); //Can add just fine, since this one is growable too!
log(names);

//Using filled to set placeholder values on a fixed length list of 3
var namesFilled = new List.filled(3, "placeholder");
log(namesFilled); //prints placeholder 3 times...
namesFilled[0] = "Joe"; //Update first entry
namesFilled[1] = "Frankie"; //Update second entry
log(namesFilled);

//Using generate (useful to create a long list of something like test data or to call a generator function)
List namesGenerated = new List.generate(3, (i) => "Name ${i}");
log(namesGenerated);
}

void log(List lst) {
lst.forEach((n) => print(n));
print('=========');
}

Looping
Looping through a list is very common. For example:

void main() {
List names = ["Joe", "Frankie", "Tom"];
for (var n in names) {
print('Hello ${n}');
}
}

What the above code does is establish a list of strings that contain names. Then we create a for loop and print the name out to the console. Here is another way to iterate that list of names:

void main() {
List names = ["Joe", "Frankie", "Tom"];
names.forEach((n) =>
print('Hello Mr. ${n}'));
}

I like the forEach approach with a fat arrow (=>) function but the examples essentially do the same thing.

Filtering
Filtering comes into play from the where method:

void main() {
List prices = [0.25, 1.00, 3.33, 0.75, 4.25, 5.99];

var overOneDollar = prices.where((p) => p > 1.00);
log(overOneDollar); //prints 3.33, 4.25, 5.99
}

void log(var lst) {
lst.forEach((n) => print(n));
}

Essentially what is happening in the above code is each price is examined in the fat arrow function and if it is greater than one dollar it passes the condition and is added to the overOneDollar result.

Mapping
Mapping allows you to take a List and transform it into something else a'la the map method. For example:

class Person
{
String firstName;
String lastName;

Person(this.firstName, this.lastName);
}

void main() {
List people = new List();
people.add(new Person("Joe", "Smithers"));
people.add(new Person("Patrick", "Thomas"));
var mappedNames = people.map((n) => 'Mr. ${n.firstName} ${n.lastName}');
log(mappedNames);
}

void log(var lst) {
lst.forEach((n) => print(n));
}

Sorting
The sort method allows you to sort. Default types like numbers and strings don't need much to get started:

void main() {
List prices = [0.25, 1.00, 3.33, 0.75, 4.25, 5.99];

prices.sort();
log(prices); //prints 0.25, 0.75, 1, 3.33, 4.25, 5.99

List alphabet = ["b", "c", "a"];
alphabet.sort();
log(alphabet); //prints a,b,c
}

void log(var lst) {
lst.forEach((n) => print(n));
}

Sorting numbers and strings is straight-forward. But what if you had a list of objects to sort? Here is an example that takes a list of Employees and ranks their Sales with the Employee with the most Sales being displayed on top and so forth:

class Sale {
int employeeId;
double price;
Sale(this.employeeId, this.price);
}

class Employee {
int id;
List sales;
Employee (this.id, this.sales);

}

void main() {
//Create a list of employees and their respective sales
List employees = new List();
employees.add(new Employee(1, [new Sale(1, 100.50), new Sale(1, 300.25)]));
employees.add(new Employee(2, [new Sale(2, 300.00), new Sale(2, 50.25), new Sale(2, 150.00)]));
employees.add(new Employee(3, [new Sale(2, 400.00), new Sale(2, 30.75), new Sale(3, 50.00)]));
//Sort so that the employee with the most sales is on top and so on...
employees.sort((a, b) => (b.sales.fold(0, (prev, element) => prev + element.price)).compareTo(a.sales.fold(0, (prev, element) => prev + element.price)));
log(employees); //prints Employee #2, followed by Employee #3, then ending with Employee #1
}

void log(var lst) {
lst.forEach((l) => print("Employee #${l.id} has ${l.sales.length} sales totaling ${l.sales.fold(0, (prev, element) => prev + element.price)} dollars!"));
}

This should give you a good start on working with lists. But you should explore the other types of collections Dart has as well.

Oldest comments (0)