Collection Operations

Working with collections in Dart is like having a toolbox full of useful utilities. Whether you're dealing with lists, sets, or maps, Dart provides powerful operations to manipulate and transform your data efficiently.

Common Collection Operations

Let's explore the most frequently used operations that work across different collection types.

forEach - Iterating Through Collections

The forEach method lets you perform an action on each element in a collection. Think of it as visiting each house on a street to deliver mail.

void main() {
  List<String> fruits = ['apple', 'banana', 'orange'];
  
  // Print each fruit
  fruits.forEach((fruit) {
    print('I love $fruit');
  });
  
  // Using forEach with maps
  Map<String, int> scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92};
  scores.forEach((name, score) {
    print('$name scored $score points');
  });
}

map - Transforming Collections

The map operation transforms each element in a collection, like having a magic wand that changes everything it touches.

void main() {
  List<int> numbers = [1, 2, 3, 4, 5];
  
  // Square each number
  List<int> squares = numbers.map((n) => n * n).toList();
  print(squares); // [1, 4, 9, 16, 25]
  
  // Convert to strings
  List<String> numberStrings = numbers.map((n) => 'Number: $n').toList();
  print(numberStrings); // [Number: 1, Number: 2, ...]
}

where - Filtering Collections

Use where to filter collections based on conditions. It's like having a bouncer at a club who only lets certain people in.

void main() {
  List<int> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  
  // Get only even numbers
  List<int> evenNumbers = numbers.where((n) => n % 2 == 0).toList();
  print(evenNumbers); // [2, 4, 6, 8, 10]
  
  // Filter strings by length
  List<String> words = ['cat', 'elephant', 'dog', 'butterfly'];
  List<String> longWords = words.where((word) => word.length > 3).toList();
  print(longWords); // [elephant, butterfly]
}

reduce and fold - Combining Elements

These operations combine all elements into a single value, like mixing ingredients to make a smoothie.

void main() {
  List<int> numbers = [1, 2, 3, 4, 5];
  
  // Sum all numbers using reduce
  int sum = numbers.reduce((a, b) => a + b);
  print('Sum: $sum'); // Sum: 15
  
  // Using fold with an initial value
  int product = numbers.fold(1, (prev, element) => prev * element);
  print('Product: $product'); // Product: 120
  
  // Concatenate strings
  List<String> words = ['Hello', 'beautiful', 'world'];
  String sentence = words.fold('', (prev, word) => prev.isEmpty ? word : '$prev $word');
  print(sentence); // Hello beautiful world
}

Advanced Collection Operations

any and every

Check if any or all elements meet a condition.

void main() {
  List<int> numbers = [2, 4, 6, 8, 10];
  
  // Check if any number is greater than 5
  bool hasLargeNumber = numbers.any((n) => n > 5);
  print('Has number > 5: $hasLargeNumber'); // true
  
  // Check if all numbers are even
  bool allEven = numbers.every((n) => n % 2 == 0);
  print('All even: $allEven'); // true
}

firstWhere and lastWhere

Find specific elements in collections.

void main() {
  List<String> names = ['Alice', 'Bob', 'Charlie', 'David'];
  
  // Find first name starting with 'C'
  String firstC = names.firstWhere((name) => name.startsWith('C'));
  print(firstC); // Charlie
  
  // Find with default value if not found
  String firstZ = names.firstWhere(
    (name) => name.startsWith('Z'),
    orElse: () => 'Not found'
  );
  print(firstZ); // Not found
}

Chaining Operations

You can chain multiple operations together for powerful data transformations:

void main() {
  List<String> words = ['hello', 'world', 'dart', 'programming', 'fun'];
  
  // Chain operations: filter long words, convert to uppercase, and sort
  List<String> result = words
      .where((word) => word.length > 4)  // Filter long words
      .map((word) => word.toUpperCase()) // Convert to uppercase
      .toList()
      ..sort(); // Sort the list
  
  print(result); // [HELLO, PROGRAMMING, WORLD]
}

Performance Tips

OperationBest ForPerformance
forEachSide effects (printing, updating)O(n)
mapTransforming elementsO(n) - lazy
whereFiltering elementsO(n) - lazy
reduce/foldCombining to single valueO(n)
any/everyBoolean checksO(n) - short-circuits

Remember that operations like map and where are lazy - they don't execute until you call toList() or iterate through the result. This can be great for performance when chaining operations!