DEV Community

WolfOf420Stret
WolfOf420Stret

Posted on • Edited on

Data Structures And Algorithms in Dart : Arrays

In Dart, there's no dedicated "array" type — ordered collections are represented by the List class. You can use a List to store a collection of items, such as a list of names or a list of numbers.

To create a List in Dart, use the List type and specify the type of elements it holds inside angle brackets (< and >):

List<int> numbers = [1, 2, 3, 4, 5];
Enter fullscreen mode Exit fullscreen mode

This creates a list of integers called numbers with the elements 1, 2, 3, 4, and 5.

A note on the new keyword: new has been optional since Dart 2, and as of Dart 3 the bare List<String>() generative constructor no longer exists at all — calling it is a compile error. To create an empty, growable list, use an empty list literal or one of the named constructors:

// Preferred: empty growable list literal
List<String> names = <String>[];

// Equivalent alternatives
List<String> names2 = List<String>.empty(growable: true);

// A fixed-length list pre-filled with a value
List<String> placeholders = List<String>.filled(3, 'placeholder');
Enter fullscreen mode Exit fullscreen mode

Lists have many useful methods for adding, removing, and manipulating elements.

We'll use the following lists to demonstrate the core List methods in Dart:

List<int> numbers = [1, 2, 3, 4, 5];
List<Object> mixed = [1, '2', 3.0, true, [4, 5]];
Enter fullscreen mode Exit fullscreen mode
  • add(element): Adds an element to the end of the list.
numbers.add(6); // [1, 2, 3, 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode
  • addAll(elements): Adds all the elements of an iterable to the end of the list.
numbers.addAll([7, 8, 9]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Enter fullscreen mode Exit fullscreen mode
  • clear(): Removes all elements from the list.
numbers.clear(); // []
Enter fullscreen mode Exit fullscreen mode
  • remove(element): Removes the first occurrence of an element from the list.
numbers.remove(3); // [1, 2, 4, 5, 6, 7, 8, 9]
Enter fullscreen mode Exit fullscreen mode
  • removeAt(index): Removes the element at a specific index from the list.
numbers.removeAt(2); // [1, 2, 5, 6, 7, 8, 9]
Enter fullscreen mode Exit fullscreen mode
  • removeLast(): Removes the last element from the list.
numbers.removeLast(); // [1, 2, 5, 6, 7, 8]
Enter fullscreen mode Exit fullscreen mode
  • removeRange(start, end): Removes a range of elements from the list.
numbers.removeRange(1, 3); // [1, 8]
Enter fullscreen mode Exit fullscreen mode
  • insert(index, element): Inserts an element at a specific index in the list.
numbers.insert(1, 2); // [1, 2, 8]
Enter fullscreen mode Exit fullscreen mode
  • insertAll(index, elements): Inserts all the elements of an iterable at a specific index in the list.
numbers.insertAll(1, [3, 4, 5]); // [1, 3, 4, 5, 2, 8]
Enter fullscreen mode Exit fullscreen mode
  • sort([compare]): Sorts the elements in the list according to the provided comparator function.
numbers.sort(); // [1, 2, 3, 4, 5, 8]
Enter fullscreen mode Exit fullscreen mode
  • indexOf(element): Returns the index of the first occurrence of an element in the list, or -1 if not found.
int index = numbers.indexOf(4); // 3
Enter fullscreen mode Exit fullscreen mode
  • lastIndexOf(element): Returns the index of the last occurrence of an element in the list, or -1 if not found.
int lastIndex = numbers.lastIndexOf(4); // 3
Enter fullscreen mode Exit fullscreen mode
  • sublist(start, [end]): Returns a new list containing the elements in a range of the list.
List<int> sublist = numbers.sublist(1, 3); // [2, 3]
Enter fullscreen mode Exit fullscreen mode
  • asMap(): Returns a new map view of the list, keyed by index.
Map<int, int> map = numbers.asMap(); // {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 8}
Enter fullscreen mode Exit fullscreen mode
  • forEach(function): Calls the provided function on each element in the list.
numbers.forEach((element) {
  print(element);
});
Enter fullscreen mode Exit fullscreen mode
  • fold(initialValue, combine): Reduces the list to a single value by repeatedly calling the combine function on the elements, starting with initialValue.
int sum = numbers.fold(0, (prev, element) => prev + element); // 15
Enter fullscreen mode Exit fullscreen mode
  • List.generate(count, generator): Creates a new list where the elements are produced by calling the generator function count times.
// Create a list of 10 random numbers
final random = Random(); // no `new` needed
List<int> randomNumbers = List.generate(10, (_) => random.nextInt(100));
Enter fullscreen mode Exit fullscreen mode
  • any(test): Returns true if at least one element of the list satisfies the provided test function.
bool anyGreaterThanFour = numbers.any((element) => element > 4); // true
Enter fullscreen mode Exit fullscreen mode
  • contains(element): Returns true if the list contains the specified element.
bool containsThree = numbers.contains(3); // true
Enter fullscreen mode Exit fullscreen mode
  • elementAt(index): Returns the element at the specified index in the list.
int elementAtIndexTwo = numbers.elementAt(2); // 3
Enter fullscreen mode Exit fullscreen mode
  • every(test): Returns true if every element of the list satisfies the provided test function.
bool allGreaterThanZero = numbers.every((element) => element > 0); // true
Enter fullscreen mode Exit fullscreen mode
  • expand(function): Returns a new list where each element is replaced by the elements returned by the function.
List<int> expanded = numbers.expand((element) => [element, element * 2]).toList();
// [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
Enter fullscreen mode Exit fullscreen mode
  • fillRange(start, end, [fillValue]): Sets the elements in a range of the list to a specified value.
numbers.fillRange(2, 5, 0); // [1, 2, 0, 0, 0]
Enter fullscreen mode Exit fullscreen mode
  • firstWhere(test, {orElse}): Returns the first element that satisfies the test function. With null safety, orElse must return a value of the list's element type (or you can omit it and let it throw if nothing matches).
int firstGreaterThanTwo = numbers.firstWhere(
  (element) => element > 2,
  orElse: () => -1,
); // 3
Enter fullscreen mode Exit fullscreen mode
  • cast<T>(): Returns a view of the list with element type T. This doesn't filter elements — it's a lazy view, and accessing an element that isn't actually of type T throws at runtime. It's meant for narrowing a list you already know is uniformly typed, not for picking elements out of a mixed list (use whereType<T>() for that).
List<num> nums = [1, 2, 3];
List<int> ints = nums.cast<int>().toList(); // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode
  • followedBy(other): Returns a new iterable containing the elements of the current list followed by the elements of another iterable.
List<int> combined = numbers.followedBy([100, 200]).toList();
Enter fullscreen mode Exit fullscreen mode
  • join([separator]): Concatenates the elements in the list into a single string, with an optional separator between each element.
String joined = mixed.join(', '); // '1, 2, 3.0, true, [4, 5]'
Enter fullscreen mode Exit fullscreen mode
  • lastWhere(test, {orElse}): Returns the last element that satisfies the test function.
Object lastBool = mixed.lastWhere(
  (element) => element is bool,
  orElse: () => false,
); // true
Enter fullscreen mode Exit fullscreen mode
  • map(function): Returns a new iterable where each element is the result of calling the function on the corresponding element of the original list.
List<int> multiplied = numbers.map((element) => element * 2).toList(); // [2, 4, 6, 8, 10]
Enter fullscreen mode Exit fullscreen mode
  • reduce(combine): Reduces the list to a single value by repeatedly calling the combine function on the elements of the list. Unlike fold, there's no initial value — the first element is used as the starting point, so the list can't be empty.
int sum = numbers.reduce((value, element) => value + element); // 15
Enter fullscreen mode Exit fullscreen mode
  • singleWhere(test, {orElse}): Returns the only element that satisfies the test function, or throws/falls back to orElse if there isn't exactly one match.
Object singleString = mixed.singleWhere(
  (element) => element is String,
  orElse: () => 'none found',
); // '2'
Enter fullscreen mode Exit fullscreen mode
  • skip(count): Returns a new iterable that skips the first count elements of the original list.
List<Object> skipped = mixed.skip(2).toList(); // [3.0, true, [4, 5]]
Enter fullscreen mode Exit fullscreen mode
  • skipWhile(test): Returns a new iterable that skips elements from the original list while they satisfy the test function.
List<Object> skippedWhile = mixed.skipWhile((element) => element is! bool).toList();
// [true, [4, 5]]
Enter fullscreen mode Exit fullscreen mode
  • take(count): Returns a new iterable containing the first count elements of the original list.
List<Object> taken = mixed.take(3).toList(); // [1, '2', 3.0]
Enter fullscreen mode Exit fullscreen mode
  • takeWhile(test): Returns a new iterable containing elements from the original list while they satisfy the test function.
List<Object> takenWhile = mixed.takeWhile((element) => element is! bool).toList();
// [1, '2', 3.0]
Enter fullscreen mode Exit fullscreen mode
  • toList(): Returns a new growable list with the elements of the original iterable.
List<Object> list = mixed.toList(); // [1, '2', 3.0, true, [4, 5]]
Enter fullscreen mode Exit fullscreen mode
  • toSet(): Returns a new set with the elements of the original list.
Set<Object> set = mixed.toSet(); // {1, '2', 3.0, true, [4, 5]}
Enter fullscreen mode Exit fullscreen mode
  • toString(): Returns a string representation of the list.
String stringified = mixed.toString(); // '[1, 2, 3.0, true, [4, 5]]'
Enter fullscreen mode Exit fullscreen mode
  • where(test): Returns a new iterable containing only the elements of the original list that satisfy the test function.
List<Object> whereBool = mixed.where((element) => element is bool).toList(); // [true]
Enter fullscreen mode Exit fullscreen mode
  • whereType<T>(): Returns a new iterable containing only the elements of the original list that are of type T.
List<double> whereDouble = mixed.whereType<double>().toList(); // [3.0]
Enter fullscreen mode Exit fullscreen mode

Modern Dart 3 list features

A few language features that have landed since the methods above were first popular, and that make day-to-day list work nicer:

  • Spread operator (... / ...?): inline one list's elements into another.
List<int> a = [1, 2, 3];
List<int> b = [0, ...a, 4]; // [0, 1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode
  • Collection if and for: build lists conditionally or iteratively without a separate loop.
bool includeZero = true;
List<int> c = [
  if (includeZero) 0,
  for (var n in a) n * n,
]; // [0, 1, 4, 9]
Enter fullscreen mode Exit fullscreen mode
  • Null-aware elements (Dart 3.8+): skip an element automatically if it evaluates to null.
int? maybeValue = getValue(); // could be null
List<int> d = [1, 2, ?maybeValue, 3];
Enter fullscreen mode Exit fullscreen mode
  • List patterns (Dart 3 pattern matching): destructure lists directly.
var [first, second, ...rest] = numbers;
print('$first, $second, $rest');
Enter fullscreen mode Exit fullscreen mode
  • Unmodifiable / const lists: prefer these when a list shouldn't change after creation.
const List<int> fixed = [1, 2, 3];
List<int> readOnlyView = List.unmodifiable([1, 2, 3]);
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
theashggl profile image
Aayush Sahay

Can't even create unnamed constructor like that for a list. Needs updation

Collapse
 
wolfof420street profile image
WolfOf420Stret

I updated it. Thank you