Продвинутые методы работы с коллекциями

Перебор элементов forEach

forEach принимает в качестве аргумента анонимную функцию колбэк, которая будет выполнена для каждого элемента коллекции.

Используем когда нужно выполнить действие для каждого элемента, не изменяя саму коллекцию и не создавая новую.

Dart - forEach

Светлая тема Темная тема
void main() {
  List languages = [
    'Dart', 'Flutter', 'Python', 'Go', 'AI'
  ];

  languages.forEach((language) {
    print('Я изучаю $language!');
  });
}

Вывод в консоль

Светлая тема Темная тема
Я изучаю Dart!
Я изучаю Flutter!
Я изучаю Python!
Я изучаю Go!
Я изучаю AI!

Преобразование элементов map

Метод map берет каждый элемент коллекции, применяет к нему заданную функцию и возвращает новую коллекцию (Iterable) с преобразованными элементами.

Dart - map

Светлая тема Темная тема
void main() {
  List numbers = [1, 2, 3, 4, 5];

  List languages = [
    'Dart', 'Flutter', 'Python', 'Go', 'AI'
  ];

  // Увеличиваем каждый элемент в 2 раза
  final result = numbers.map((number) => number * 2);
  print(result.toList());

  // Узнаём длину каждой строки
  final result2 = languages.map((language) => language.length);
  print(result2.toList());
}

Вывод в консоль

Светлая тема Темная тема
[2, 4, 6, 8, 10]
[4, 7, 6, 2, 2] // Длина каждой строки в списке languages

Фильтрация элементов where

Метод where берет каждый элемент, применяет к нему условие (функцию, которая возвращает true или false) и возвращает новую коллекцию (Iterable), содержащую только те элементы, для которых условие вернуло true.

Dart - where

Светлая тема Темная тема
  List> students = [
    {'name': 'Артём', 'mark': 70},
    {'name': 'Анна', 'mark': 85},
    {'name': 'Наташа', 'mark': 65},
    {'name': 'Юля', 'mark': 90},
  ];

  // Все студенты которые набрали больше 70 баллов
  final result3 = students.where((student) => student['mark'] >= 70);
  print(result3.toList());

  // Все студенты имена которых начинаются с буквы А
  final result4 = students.where((student) => student['name'].startsWith('А'));
  print(result4.toList());

Вывод в консоль

Светлая тема Темная тема
// Все студенты которые набрали больше 70 баллов
[
  {name: Артём, mark: 70}, 
  {name: Анна, mark: 85}, 
  {name: Юля, mark: 90}
]

// Все студенты имена которых начинаются с буквы А
[
  {name: Артём, mark: 70}, 
  {name: Анна, mark: 85}
]

Поиск конкретного элемента firstWhere lastWhere

Иногда нужен не список отфильтрованных элементов, а первый (или последний) элемент, который соответствует условию.

Оба метода могут принимать необязательный параметр orElse, который является функцией, возвращающей значение, если элемент не найден.

Dart - firstWhere

Светлая тема Темная тема
List languages = ['Dart', 'Flutter', 'Python', 'Go', 'AI'];
  
// Найти первый элемент длина которого меньше 3
final result5 = languages.firstWhere(
  (language) => language.length < 3,
  orElse: () => 'Нет такого элемента',
);

print(result5); // Go

Проверка соответствия условиям any и every

Иногда не нужно получать элементы, а просто проверить, соответствует ли хотя бы один элемент условию или все элементы условию.

any возвращает true, если хотя бы один элемент коллекции соответствует заданному условию.
every возвращает true, если все элементы коллекции соответствуют заданному условию.

Dart - any, every

Светлая тема Темная тема
List numbers = [1, 2, 3, 4, 5];
List languages = ['Dart', 'Flutter', 'Python', 'Go', 'AI'];

// Хоть одно число является чётным?
final result6 = numbers.any((number) => number % 2 == 0);
print(result6); // true

// Все ли числа положительные?
final result7 = numbers.every((number) => number > 0);
print(result7); // true

// Все языки программирования начинаются с буквы D?
final result8 = languages.every((language) => language.startsWith('D'));
print(result8); // false

Свертывание (агрегация) коллекции fold (reduce)

Методы fold и reduce используются для агрегации (или "свертывания") коллекции в одно единственное значение. Это может быть сумма всех чисел, конкатенация всех строк, или даже создание нового объекта на основе всех элементов.

reduce: Объединяет элементы коллекции в одно значение, используя заданную функцию. Не имеет начального значения. Начинает с первого и второго элемента. Если коллекция пуста, будет ошибка.

fold: То же, что reduce, но позволяет указать начальное значение (initial value). Это делает его более безопасным для пустых коллекций.

Dart - fold, reduce

Светлая тема Темная тема
List numbers = [1, 2, 3, 4, 5];
List> students = [
  {'name': 'Артём', 'mark': 70},
  {'name': 'Анна', 'mark': 85},
  {'name': 'Наташа', 'mark': 65},
  {'name': 'Юля', 'mark': 90},
];

// Сумма всех значений через reduce
final result9 = numbers.reduce((value, element) => value + element);
print(result9); // 15

// Сумма всех значений через fold
final result10 = numbers.fold(0, (prev, element) => prev + element);
print(result10); // 15

// Получить строку всех имен студентов баллы которых больше 65 через reduce
final result11 = students
  .where((student) => student['mark'] > 65)
  .map((student) => student['name'])
  .reduce((value, element) => '$value, $element');

print(result11); // Артём, Анна, Юля

taketakeWhile()skipWhile()

takeWhile() возвращает Iterable, содержащий все элементы, которые находятся ДО элемента, удовлетворяющему условию в колбэке.

skipWhile() возвращает Iterable, содержащий все элементы, которые находятся ПОСЛЕ элемента, удовлетворяющему условию в колбэке.

Dart - take, skip

Светлая тема Темная тема
final values = [-22, 1, 45, 68, 98, 0, 100, 2, 3, 42, 11];
 
print(values.takeWhile((value) => value != 0)); // (-22, 1, 45, 68, 98)
print(values.skipWhile((value) => value != 0)); // (0, 100, 2, 3, 42, 11)

// take(n) - вернуть n элементов коллекции
print(values.take(4)); // (-22, 1, 45, 68)