Collections
## Learning Objectives
- Work with Lists, Sets, and Maps
- Master collection methods
- Use collection conditionals and spreads
- Filter and transform collections
## Lists
### Creating Lists
```dart
void main() {
// Empty list
var empty = [];
// With initial values
var numbers = [1, 2, 3, 4, 5];
// Fixed-length list
var fixed = List.filled(3, 0);
// Growable list
var growable = List.empty(growable: true);
growable.add(1);
growable.add(2);
}
```
### Accessing Elements
```dart
void main() {
var list = ['apple', 'banana', 'orange'];
print(list[0]); // apple
print(list.first); // apple
print(list.last); // orange
print(list.length); // 3
// Negative index
print(list[-1]); // Error: invalid
}
```
### Modifying Lists
```dart
void main() {
var list = [1, 2, 3];
list.add(4); // [1, 2, 3, 4]
list.addAll([5, 6]); // [1, 2, 3, 4, 5, 6]
list.insert(0, 0); // [0, 1, 2, 3, 4, 5, 6]
list.remove(3); // removes first 3
list.removeAt(0); // removes first element
list.clear(); // []
}
```
### List Methods
```dart
void main() {
var list = [3, 1, 4, 1, 5, 9, 2, 6];
// Sorting
var sorted = List.from(list)..sort();
print(sorted); // [1, 1, 2, 3, 4, 5, 6, 9]
// Reversing
print(list.reversed.toList()); // [6, 2, 9, 5, 1, 4, 1, 3]
// Searching
print(list.indexOf(4)); // 2
print(list.lastIndexOf(1)); // 3
print(list.contains(5)); // true
// Slicing
print(list.sublist(2, 5)); // [4, 1, 5]
}
```
## Sets
### Creating Sets
```dart
void main() {
// Empty set
var empty = {};
// With values
var fruits = {'apple', 'banana', 'orange'};
// From list (duplicates removed)
var unique = {1, 2, 3, 3, 3}; // {1, 2, 3}
}
```
### Set Operations
```dart
void main() {
var a = {1, 2, 3, 4};
var b = {3, 4, 5, 6};
// Union
print(a.union(b)); // {1, 2, 3, 4, 5, 6}
// Intersection
print(a.intersection(b)); // {3, 4}
// Difference
print(a.difference(b)); // {1, 2}
// Contains
print(a.contains(3)); // true
print(a.containsAll(b)); // false
}
```
### Modifying Sets
```dart
void main() {
var set = {1, 2, 3};
set.add(4); // {1, 2, 3, 4}
set.addAll([5, 6]); // {1, 2, 3, 4, 5, 6}
set.remove(2); // {1, 3, 4, 5, 6}
set.removeAll({5, 6}); // {1, 3, 4}
set.clear(); // {}
}
```
## Maps
### Creating Maps
```dart
void main() {
// Empty map
var empty = {};
// With values
var ages = {'Alice': 30, 'Bob': 25};
// Using Map constructor
var map = Map();
map['name'] = 'Alice';
map['active'] = true;
}
```
### Accessing Maps
```dart
void main() {
var ages = {'Alice': 30, 'Bob': 25};
print(ages['Alice']); // 30
print(ages['unknown']); // null
// With default
print(ages['unknown'] ?? 0); // 0
// Keys and values
print(ages.keys); // (Alice, Bob)
print(ages.values); // (30, 25)
print(ages.length); // 2
}
```
### Modifying Maps
```dart
void main() {
var map = {};
map['a'] = 1; // {a: 1}
map.addAll({'b': 2, 'c': 3}); // {a: 1, b: 2, c: 3}
map.remove('b'); // {a: 1, c: 3}
map.clear(); // {}
}
```
### Map Methods
```dart
void main() {
var ages = {'Alice': 30, 'Bob': 25, 'Charlie': 35};
// Contains
print(ages.containsKey('Alice')); // true
print(ages.containsValue(30)); // true
// Iterate
for (var entry in ages.entries) {
print('${entry.key}: ${entry.value}');
}
// Map transformation
var names = ages.keys.where((k) => k.startsWith('C')).toList();
print(names); // [Charlie]
var doubled = ages.map((k, v) => MapEntry(k, v * 2));
print(doubled); // {Alice: 60, Bob: 50, Charlie: 70}
}
```
## Collection Conditionals
### If Elements
```dart
void main() {
var needsLogin = true;
var widgets = [
Text('Title'),
if (needsLogin) Text('Login'),
Text('Footer'),
];
}
```
### If-Else Elements
```dart
void main() {
var isPremium = false;
var items = [
Text('Item 1'),
if (isPremium)
Text('Premium Feature')
else
Text('Basic Feature'),
];
}
```
## Collection Spreads
### Spread Operator
```dart
void main() {
var a = [1, 2, 3];
var b = [0, ...a, 4]; // [0, 1, 2, 3, 4]
// Null-aware spread
List? nullable;
var c = [0, ...?nullable, 4]; // [0, 4]
}
```
### Spread with Maps
```dart
void main() {
var defaults = {'a': 1, 'b': 2};
var overrides = {'b': 3, 'c': 4};
var combined = {...defaults, ...overrides};
print(combined); // {a: 1, b: 3, c: 4}
}
```
## Collection For
```dart
void main() {
var items = ['a', 'b', 'c'];
var widgets = [
for (var item in items) Text(item),
];
// Equivalent to:
// var widgets = items.map((item) => Text(item)).toList();
}
```
### With Index
```dart
void main() {
var items = ['a', 'b', 'c'];
var numbered = [
for (var i = 0; i < items.length; i++)
'${i + 1}: ${items[i]}',
];
print(numbered); // [1: a, 2: b, 3: c]
}
```
## Collection Methods
### forEach
```dart
void main() {
[1, 2, 3].forEach((n) => print(n));
}
```
### map
```dart
void main() {
var doubled = [1, 2, 3].map((n) => n * 2).toList();
print(doubled); // [2, 4, 6]
}
```
### where
```dart
void main() {
var evens = [1, 2, 3, 4, 5].where((n) => n % 2 == 0).toList();
print(evens); // [2, 4]
}
```
### reduce and fold
```dart
void main() {
// reduce - accumulates to single value
var sum = [1, 2, 3, 4].reduce((a, b) => a + b);
print(sum); // 10
// fold - with initial value
var product = [1, 2, 3, 4].fold(1, (a, b) => a * b);
print(product); // 24
}
```
### any and every
```dart
void main() {
var list = [1, 2, 3, 4, 5];
// any - at least one matches
print(list.any((n) => n > 4)); // true
// every - all match
print(list.every((n) => n > 0)); // true
}
```
### firstWhere and singleWhere
```dart
void main() {
var list = [1, 2, 3, 4, 5];
// firstWhere - first element matching
print(list.firstWhere((n) => n > 2)); // 3
// singleWhere - only element matching
var singles = [3].singleWhere((n) => n > 2);
print(singles); // 3
}
```
## Summary
- List: ordered, index-accessible, allows duplicates
- Set: unordered, unique elements
- Map: key-value pairs
- Collection if/for: inline conditionals and loops
- Spread: `...` and `...?` for collection composition
- Common methods: map, where, reduce, fold, forEach, any, every
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →