๐ŸŽ“ A1Learner
๐Ÿ”
0 of 24 lessons completed

Dart Collection Patterns

A collection pattern matches the shape of a list or a map. It binds the elements or values it finds to new variables in one step.

A list destructure with a rest pattern

The pattern takes the first two elements by name. The rest pattern collects the remaining elements into a new list.

void main() {
  var [first, second, ...rest] = [1, 2, 3, 4];
  print(first);
  print(second);
  print(rest);
}

List patterns in a switch

The first case fits a list of exactly two numbers and adds them. The second case fits a single number, and the longer list reaches the wildcard case.

void main() {
  var values = [
    [10, 20],
    [7],
    [1, 2, 3]
  ];
  for (var value in values) {
    switch (value) {
      case [var a, var b]:
        print('pair sum ${a + b}');
      case [var only]:
        print('single $only');
      case _:
        print('other shape');
    }
  }
}

A map pattern in a declaration

The pattern names two keys of the data map and gives a type to each bound value. The print reads the new variables, not the map.

void main() {
  Map<String, dynamic> data = {'name': 'Ana', 'age': 30};
  var {'name': String name, 'age': int age} = data;
  print('$name is $age');
}

Map patterns as switch cases

The first case needs both keys and the exact value true under the ok key. The second case needs only the count key.

void main() {
  Object data = {'count': 3, 'ok': true};
  switch (data) {
    case {'count': int c, 'ok': true}:
      print('count $c ready');
    case {'count': int c}:
      print('count $c');
    case _:
      print('other data');
  }
}

Example

void main() {
  var groups = [
    [1, 2],
    [3]
  ];
  switch (groups) {
    case [[var a, var b], [var c]]:
      print('total ${a + b + c}');
    case _:
      print('other shape');
  }
}

Key points

  • A list pattern matches a list by its length and by the shape of its elements.
  • A rest pattern written with ... collects the elements that the earlier patterns did not take.
  • A list pattern can appear in a variable declaration and in a switch case.
  • A map pattern matches a map by its keys and binds the value stored under each key.
  • A map pattern can write a type before a bound name, so the stored value must match that type too.
  • A value whose shape does not fit a case moves on to the next case of the switch.

In this example, the case pattern holds two list patterns inside one outer list pattern. The first inner pattern binds 1 and 2, and the second inner pattern binds 3. The print adds the three bound values and shows 6.

Note

The rest pattern comes last in a list pattern, because it takes everything that is left.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท DartPad

Exercise

What does rest hold after var [first, ...rest] = [1, 2, 3]; runs?