ZetCode

Dart List

last modified December 8, 2020

Dart List tutorial shows how to work with a List collection in Dart language.

A list is an indexable collection of objects with a length. The indexes start from zero. It is possible to create growable or fixed-length lists. By default, we create growable lists with [].

It is generally not allowed to modify the list's length (adding or removing elements) while an operation on the list is being performed, for example during a call to forEach or sort. Also, trying to change the length of a list during iteration leads to ConcurrentModificationError.

It is possible to create dynamic lists or lists restricted to a specified data type.

Dart List simple example

The following is a simple example with a list in Dart.

simple.dart
void main() {
  var vals = <int>[1, 2, 3, 4, 5];

  var e1 = vals.first;
  var e2 = vals.last;
  var e3 = vals.elementAt(1);

  var len = vals.length;

  print('There are $len elements in the list');
  print('The first element is $e1');
  print('The last element is $e2');
  print('The second element is $e3');
}

In the example, we have a list of integers. We use three attributues and one method on the list.

var vals = <int>[1, 2, 3, 4, 5];

We create a list with the [] characters; the list elements are separated by a comma character. The list is restricted to integers with <int>.

var e1 = vals.first;
var e2 = vals.last;

We get the first and the last elements of the list with the first and last attributues.

var e3 = vals.elementAt(1);

We get the second element of the list with elementAt.

var len = vals.length;

We get the size of the list with the length attribute.

$ dart simple.dart
There are 5 elements in the list
The first element is 1
The last element is 5
The second element is 2

Dart initialize list

We can initialize a list in different ways.

initialize.dart
void main() {
  List<String> words = [
    'sky',
    'cloud',
    'tent',
    'tree',
    'falcon',
  ];
  print(words);

  var vals1 = List<int>.filled(8, 1);
  print(vals1);

  var vals2 = List<int>.generate(10, (n) => n * n);
  print(vals2);

  var vals3 = List.of(<int>{2, 4, 6, 8});
  vals3.add(10);
  print(vals3);

  var vals4 = List<int>.empty(growable: true)..length = 3;

  vals4[0] = 1;
  vals4[1] = 2;
  vals4[2] = 3;
  print(vals4);

  var vals5 = List<int>.unmodifiable(vals3);
  print(vals5);
}

In the example, we create and initialize a few lists using different ways of initialization.

List<String> words = [
  'sky',
  'cloud',
  'tent',
  'tree',
  'falcon',
];

We create a list of words. Before the variable name, we specify the List and its data type.

var vals1 = List<int>.filled(8, 1);
print(vals1);

With the filled method, we create a list of the given length with the specified value at each position.

var vals3 = List.of(<int>{2, 4, 6, 8});
vals3.add(10);
print(vals3);

Using of, we create a list from the given iterable -- a set in our case. We add a new value with add.

var vals4 = List<int>.empty(growable: true)..length = 3;

vals4[0] = 1;
vals4[1] = 2;
vals4[2] = 3;

We create an empty list with empty. The growable option controls whether the list is growable or fixed. We also set the length of the list with the length attribute. Later, we assign three values to the list.

var vals5 = List<int>.unmodifiable(vals3);

With unmodifiable, we create a list that cannot be changed. An unmodifiable list cannot have its length or elements changed.

$ dart initialize.dart
[sky, cloud, tent, tree, falcon]
[1, 1, 1, 1, 1, 1, 1, 1]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[2, 4, 6, 8, 10]
[1, 2, 3]
[2, 4, 6, 8, 10]

Dart empty list

With isEmpty and isNotEmpty, we can determine whether the list is empty or not empty.

empty.dart
void main() {
  List<int> vals = [];

  if (vals.isEmpty) {
    print('the list is empty');
  }

  vals.add(1);
  vals.add(2);
  vals.add(3);

  if (vals.isNotEmpty) {
    print('the list is not empty');
  }

  vals.clear();

  if (vals.isEmpty) {
    print('the list is empty');
  }
}

In the example, we use the isEmpty and isNotEmpty methods.

$ dart empty.dart
the list is empty
the list is not empty
the list is empty

Dart dynamic list

We can create a dynamic list which can take elements of various data types.

dynamic.dart
void main() {
  var nums = <int>[1, 2, 3];
  print('$nums - ${nums.runtimeType}');

  var items = [1, 2.0, "three"];
  print('$items - ${items.runtimeType}');

  List<dynamic> items2 = List.of(items);
  print('$items2 - ${items2.runtimeType}');

  var vals = [1, 2.0, 3.0, 1.0, 4, 5, 6, 7, 8.0];
  print('$vals - ${vals.runtimeType}');
}

The example creates dynamic and non-dynamic lists.

var nums = <int>[1, 2, 3];
print('$nums - ${nums.runtimeType}');

This is a list restricted to integers.

var items = [1, 2.0, "three"];
print('$items - ${items.runtimeType}');

Here we have a list which contains an integer, a double, and a string. The compiler creates a list of objects.

List<dynamic> items2 = List.of(items);
print('$items2 - ${items2.runtimeType}');

Here we explicitly specify a dynamic list.

var vals = [1, 2.0, 3.0, 1.0, 4, 5, 6, 7, 8.0];
print('$vals - ${vals.runtimeType}');

Finally, we create list of elements of numeric data type.

$ dart dynamic.dart
[1, 2, 3] - List<int>
[1, 2.0, three] - List<Object>
[1, 2.0, three] - List<dynamic>
[1, 2.0, 3.0, 1.0, 4, 5, 6, 7, 8.0] - List<num>

Dart reversed list

The reversed property returns an iterable of the values from the list in reverse order.

reversed.dart
void main() {
  var vals = <int>[8, 4, 1, 2, 4, 5, 9];

  var reversed = List.of(vals.reversed);
  print(reversed);
}

In the example, we create a reversed iterable with the reversed attribute and then we create a list from the iteratble with List.of.

$ dart reversed.dart
[9, 5, 4, 2, 1, 4, 8]

Dart list iteration

We can loop over the elements of a list with forEach, for, or while loops.

iterate.dart
import 'dart:io';

void main() {
  var vals = <int>[1, 2, 3, 4, 5];

  vals.forEach((e) {
    stdout.write("$e ");
  });
  print("");

  for (var e in vals) {
    stdout.write("$e ");
  }
  print("");

  for (int i = 0; i < vals.length; i++) {
    stdout.write("${vals[i]} ");
  }
  print("");

  var lit = vals.iterator;

  while (lit.moveNext()) {
    stdout.write("${lit.current} ");
  }

  print("");

  int i = 0;

  while (i < vals.length) {
    stdout.write("${vals[i]} ");
    i++;
  }
  print("");
}

The example presents five ways of iteration.

vals.forEach((e) {
  stdout.write("$e ");
});

With the forEach method, we go through the elements one by one.

for (var e in vals) {
  stdout.write("$e ");
}

The for-range statement is similar to the forEach method.

for (int i = 0; i < vals.length; i++) {
  stdout.write("${vals[i]} ");
}

Here we iterate over the elements with the classic for loop.

while (lit.moveNext()) {
  stdout.write("${lit.current} ");
}

We go through the elements of the list using while loop and the moveNext method.

int i = 0;

while (i < vals.length) {
  stdout.write("${vals[i]} ");
  i++;
}

Here we loop over the list with the while loop; this time we use the length property and the i counter.

$ dart iterate.dart
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

Dart List collection if & for forms

With the collection if and for forms, we can dynamically create lists in Dart. The syntax is close to list comprehensions known from Haskell or Python.

collection_if_for.dart
void main() {
  var integers = [for (var i = 1; i < 10; i++) i];
  var squares = [for (var n in integers) n * n];
  var evens = [
    for (var n in integers)
      if (n % 2 == 0) n
  ];

  print(integers);
  print(squares);
  print(evens);
}

The example creates a three lists with a collection if/for form.

var integers = [for (var i = 1; i < 10; i++) i];

We create a list of integers 1..9.

var squares = [for (var n in integers) n * n];

Here, we create a new list based on existing list. The elements of the new list are squares of the integers list.

var evens = [
  for (var n in integers)
    if (n % 2 == 0) n
];

We picku up even values from the integers list. We utilize the if form to include only values that are even.

$ dart collection_if_for.dart
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[2, 4, 6, 8]

Dart unique elements

In the following example, we create a list of unique elements.

unique_elements.dart
void main() {
  var vals = <int>[1, 1, 1, 2, 2, 2, 3, 3, 4, 5];

  var res = vals.toSet().toList();
  print(res);

  var res2 = [
    ...{...vals}
  ];
  print(res2);
}

We have a list of integers which contains duplicates. We use two ways to create a unique list from it.

var res = vals.toSet().toList();
print(res);

In the first way, we use the toSet and the toList methods.

var res2 = [
  ...{...vals}
];

In the second way, we use the spread operator.

$ dart unique_elements.dart
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

Dart list add elements

We can add elements at the end of the list or at the specified index.

adding.dart
void main() {
  var vals = <int>[1, 2, 3];

  vals.add(4);
  vals.addAll([5, 6, 7]);

  vals.insert(0, 0);
  vals.insertAll(vals.length, [8, 9, 10]);

  print(vals);
}

We have a list of integers to which we add new elements.

vals.add(4);

We add a single value at the end of the list with add.

vals.addAll([5, 6, 7]);

We add all three elements at the end with addAll.

vals.insert(0, 0);

We insert a single value at the specified position with insert.

vals.insertAll(vals.length, [8, 9, 10]);

We insert all values at the specified position with insertAll.

$ dart adding.dart
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Dart list remove elements

In the following example, we use methods for removing elements.

removing.dart
void main() {
  var vals = <int>[1, 2, 3, 4, 5, 6];

  vals.remove(1);
  print(vals);

  vals.removeAt(vals.length - 1);
  print(vals);

  vals.removeLast();
  print(vals);

  vals.clear();
  print(vals);

  print('---------------');

  var vals2 = <int>[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  vals2.removeWhere((e) => e < 0);
  print(vals2);

  vals2.removeRange(0, 5);
  print(vals2);

  vals2.retainWhere((e) => e > 7);
  print(vals2);
}

The example removes elements from lists of integers.

vals.remove(1);

The remove method removes the first occurrence of value 1 from the list.

vals.removeAt(vals.length - 1);

The removeAt method removes an element at the given index.

vals.clear();

The clear method removes all elements.

vals2.removeWhere((e) => e < 0);

With removeWhere, we delete all elements that satisfy the given predicate. In our case, we delete all negative values.

vals2.removeRange(0, 5);

The removeRange method removes values in the given range, where the starting index is inclusive and the ending is exclusive.

vals2.retainWhere((e) => e > 7);

The retainWhere method removes all values that fail to satisfy the given condition. In our case, we keep values greater than 7 and remove the rest of the elements.

$ dart removing.dart
[2, 3, 4, 5, 6]
[2, 3, 4, 5]
[2, 3, 4]
[]
---------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[5, 6, 7, 8, 9, 10]
[8, 9, 10]

Dart filter list

The following example shows how to do list filtering.

filter.dart
void main() {
  var vals = <int>[-1, 3, 2, 0, 1, -3, 4, 3, 5];
  var positive = vals.where((e) => e > 0);
  print(positive);

  var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
  var w3 = words.where((e) => e.length == 3);
  print(w3);

  var e1 = words.firstWhere((e) => e.startsWith('w'));
  print(e1);

  var e2 = words.lastWhere((e) => e.startsWith('w'));
  print(e2);
}

The example filters a list of integers and words.

var vals = <int>[-1, 3, 2, 0, 1, -3, 4, 3, 5];
var positive = vals.where((e) => e > 0);

With the where method, we filter out all positive values.

var words = <String>["wolf", "sky", "falcon", "cloud", "wood", "oak"];
var w3 = words.where((e) => e.length == 3);

Here we create a new list consisting of words that have three characters.

var e1 = words.firstWhere((e) => e.startsWith('w'));

With firstWhere, we get the first word that starts with the 'w' character.

var e2 = words.lastWhere((e) => e.startsWith('w'));

With lastWhere, we get the last word that starts with the 'w' character.

$ dart filter.dart
(3, 2, 1, 4, 3, 5)
(sky, oak)
wolf
wood

Dart list map

With the map method, we apply the supplied function on each element of the list.

mapping.dart
import 'dart:math';

void main() {
  var vals = <int>[1, 2, 3, 4, 5];

  var powered = vals.map((e) => pow(e, 2));

  for (var e in powered) {
    print(e);
  }
}

In the example, we apply the pow method on each element using map.

$ dart mapping.dart
1
4
9
16
25

Dart list every

The every method checks whether every element of the list satisfies the given condition.

everymet.dart
class User {
  String firstName;
  String lastName;
  bool married;

  User(this.firstName, this.lastName, this.married);

  bool get isMarried => this.married;

  @override
  String toString() => "${this.firstName} ${this.lastName} ${this.married}";
}

void main() {
  var users = <User>[
    User('John', 'Doe', true),
    User('Jane', 'Doe', true),
    User('Peter', 'Smith', false),
    User('Roger', 'Roe', true),
    User('Martin', 'Fonda', false),
  ];

  var allMarried = users.every((e) => e.isMarried);
  if (allMarried) {
    print('all users are married');
  } else {
    print('not all users are married');
  }
}

We have a list of users. We check if all users are married utilizing the every method.

$ dart everymet.dart
not all users are married

Dart list partitions

Dart provides list methods for doing partition operations.

partitions.dart
void main() {
  var vals = <int>[1, 2, 0, 4, 3, 6, 5];

  var res = vals.skip(2);
  print(res);

  var res2 = vals.skipWhile((e) => e <= 4);
  print(res2);

  var res3 = vals.take(4);
  print(res3);

  var res4 = vals.takeWhile((e) => e <= 4);
  print(res4);
}

In the example, we show four partitioning operations.

var res = vals.skip(2);

The skip method returns an iterable that provides all but the first two elements.

var res2 = vals.skipWhile((e) => e <= 4);

The skipWhile method returns an iterable that skips the leading elements while the condition is satisfied.

var res3 = vals.take(4);

The take method returns an iterable of the four first elements of the list.

var res4 = vals.takeWhile((e) => e <= 4);

The takeWhile method returns an iterable of the leading elements that satisfy the supplied condition.

$ dart partitions.dart
(0, 4, 3, 6, 5)
(6, 5)
(1, 2, 0, 4)
(1, 2, 0, 4, 3)

Dart list reduce

The reduce method reduces a list to a single value by iteratively combining elements of the list using the provided function.

reducing.dart
void main() {
  var vals = <int>[1, 2, 3, 4, 5];

  var sum = vals.reduce((sum, e) => sum += e);
  var product = vals.reduce((product, e) => product *= e);

  print('The sum is $sum');
  print('The product is $product');
}

The example produces a sum and a product of integer values with reduce.

$ dart reducing.dart
The sum is 15
The product is 120

In this tutorial, we have covered Dart lists.

List all Dart tutorials.