Книга: Выразительный JavaScript
Абстрагируем обход массива
Абстрагируем обход массива
Простые функции, которые мы использовали раньше, хороши для построения абстракций. Но иногда их бывает недостаточно.
В предыдущей главе мы несколько раз встречали такой цикл:
var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
var current = array[i];
console.log(current);
}
Код пытается сказать: «для каждого элемента в массиве – вывести его в консоль». Но он использует обходной путь – с переменной для подсчёта i
, проверкой длины массива, и объявлением дополнительной переменной current
. Мало того, что он не очень красив, он ещё и является почвой для потенциальных ошибок. Мы можем случайно повторно использовать переменную i
, вместо length
написать lenght
, перепутать переменные i
и current
, и т. п.
Давайте абстрагируем его в функцию. Можете придумать способ это сделать?
Довольно просто написать функцию, обходящую массив и вызывающую для каждого элемента console.log
.
function logEach(array) {
for (var i = 0; i < array.length; i++)
console.log(array[i]);
}
Но что, если нам надо делать что-то другое, нежели выводить элементы в консоль? Поскольку «делать что-то» можно представить как функцию, а функции – это просто переменные, мы можем передать это действие как аргумент:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
forEach(["Тили", "Мили", "Трямдия"], console.log);
// ? Тили
// ? Мили
// ? Трямдия
Часто можно не передавать заранее определённую функцию в forEach
, а создавать функцию прямо на месте.
var numbers = [1, 2, 3, 4, 5], sum = 0;
forEach(numbers, function(number) {
sum += number;
});
console.log(sum);
// ? 15
Выглядит похоже на классический цикл for
, с телом цикла, записанным в блоке. Однако, теперь тело находится внутри функции, и также внутри скобок вызова forEach
. Поэтому его нужно закрыть как фигурной, так и круглой скобкой.
Используя этот шаблон, мы можем задать имя переменной для текущего элемента массива (number
), без необходимости выбирать его из массива вручную.
Вообще, нам даже не нужно писать самим forEach
. Это стандартный метод массивов. Так как массив уже передан в качестве переменной, над которой мы работаем, forEach
принимает только один аргумент – функцию, которую нужно выполнить для каждого элемента.
Для демонстрации удобства этого подхода вернёмся к функции из предыдущей главы. Она содержит два цикла, проходящих по массивам:
function gatherCorrelations(journal) {
var phis = {};
for (var entry = 0; entry < journal.length; entry++) {
var events = journal[entry].events;
for (var i = 0; i < events.length; i++) {
var event = events[i];
if (!(event in phis))
phis[event] = phi(tableFor(event, journal));
}
}
return phis;
}
Используя forEach
мы делаем запись чуть короче и гораздо чище.
function gatherCorrelations(journal) {
var phis = {};
journal.forEach(function(entry) {
entry.events.forEach(function(event) {
if (!(event in phis))
phis[event] = phi(tableFor(event, journal));
});
});
return phis;
}
- Почему необходима миграция
- Уменьшение времени, необходимого для резервного копирования и восстановления
- Новые функции API для работы с Blob и массивами
- Обход дерева
- Определение необходимого системного вызова
- 9.2 Реализация массива ftAID на платформе Windows NT
- Добавление списка необходимых предметов
- Глава 2. Что необходимо для беспроводной связи
- Можно ли избавиться от необходимости использовать двойной щелчок кнопкой мыши при открытии папки?
- 7.6. Обход элементов массива
- 4.13.2. Обход сетевого экрана
- 5.13. Необходимый набор программ, для полноценной работы на компьютере