# Patterns and Switch Expressions — Dart

Source: https://www.skillbyai.com/en/dart/m-patterns

> Match and destructure data with patterns in switch, if-case and variable declarations.

## Asking questions about the shape of data

Dart 3 **patterns** test a value's shape and extract parts of it. Pattern kinds include **constant** patterns (`404`), **relational** patterns (`>= 500`), **logical** `||` and `&&`, **type tests** (`int n`), **object** patterns (`Point(x: 0, :final y)`), **list** patterns (`[first, ..., last]`, with `...` for the rest), **map** patterns (`{'status': 'ok', 'data': final data}`), **record** patterns and **wildcards** (`_`). They work in **`switch` statements and expressions**, in **`if-case`** (`if (json case {'name': String name})`), in variable declarations and in `for` loops. **Switch expressions** (`final label = switch (code) { 200 => 'OK', >= 500 => 'Server error', _ => 'Other' };`) return values concisely. **Guard clauses** with `when` add conditions. Over sealed types, enums and bools, switches are checked for **exhaustiveness**. Map patterns are particularly useful for validating decoded JSON, replacing chains of `is` checks and casts.

## Validating JSON with patterns

Map and list patterns check structure and extract values in one step.

```dart
import 'dart:convert';

String describeStatus(int code) => switch (code) {
      200 || 201 => 'Success',
      >= 400 && < 500 => 'Client error',
      >= 500 => 'Server error',
      _ => 'Unexpected',
    };

String summarise(Object? json) {
  if (json case {'id': String id, 'items': [_, ...] && List items, 'total': num total}) {
    return 'Order $id: ${items.length} items, total $total';
  }
  return 'Invalid order payload';
}

String firstAndLast(List<int> values) => switch (values) {
      [] => 'empty',
      [final only] => 'only $only',
      [final first, ..., final last] => 'from $first to $last',
    };

void main() {
  final payload = jsonDecode('{"id":"o-7","items":[{"sku":"pen"}],"total":99}');
  print(summarise(payload));          // Order o-7: 1 items, total 99
  print(describeStatus(503));
  print(firstAndLast([3, 8, 15]));
}
```

## A customs officer with a checklist

A pattern is a customs officer who checks each parcel against a description ("has an id string and a non-empty item list") and, if it matches, hands you the labelled contents directly instead of making you open it yourself.

**Quiz:** What does the list pattern `[final first, ..., final last]` match?

- [ ] Only lists with exactly three elements
- [ ] Empty lists
- [ ] Maps
- [x] Lists with at least two elements, binding the first and last

*Answer:* Lists with at least two elements, binding the first and last. The rest element ... matches any number of elements between first and last.
