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?