Статьи

Вернуться к основам: Array Extras

Массивы являются фундаментальной структурой данных во многих языках программирования, и JavaScript не является исключением. Чтобы абстрагироваться от многих деталей работы с массивами, JavaScript предоставляет набор функций, известных как дополнения к массивам. В этой статье описываются различные дополнительные функции массива и их использование.

Фон

Почти все операции с массивами выполняются путем зацикливания каждого элемента массива, по одному за раз. Например, следующий код использует цикл for для записи всех элементов массива в консоль отладки.

 var foo = ["a", "b", "c", "d"]; for (var i = 0, len = foo.length; i < len; i++) { console.log(foo[i]); } 

Прежде всего, вы должны понимать, что предыдущий пример — это очень хороший код JavaScript. Однако, если у вас есть несколько сложных циклов, отслеживать переменные может быть утомительно. Дополнительные функции массива позволяют нам заменять целые циклы вызовами функций, что часто улучшает читаемость кода. Теперь давайте посмотрим на различные дополнения массива.

forEach()

Как и многие дополнительные forEach() массива, метод forEach() является функцией более высокого порядка — функцией, которая получает другую функцию в качестве аргумента. Вместо циклического перебора элементов массива forEach() вызывает функцию обратного вызова для каждого элемента по очереди. Функция обратного вызова принимает три аргумента — текущий элемент массива, индекс массива и сам массив. В следующем коде исходный пример был переписан для использования метода forEach() .

 ["a", "b", "c", "d"].forEach(function(element, index, array) { console.log(element); }); 

Обратите внимание, что использование forEach() устраняет необходимость в нотации цикла и индексации массива. Кроме того, поскольку JavaScript использует определение уровня функции, функция обратного вызова forEach() предоставляет новую область, позволяя повторно использовать имена переменных. Единственный недостаток — снижение производительности, вызванное вызовом функции для каждого элемента в массиве. К счастью, этот штраф часто ничтожен. Также обратите внимание, что вы можете передать необязательный аргумент forEach() после функции обратного вызова. Если присутствует, этот второй аргумент определяет значение this используемое в функции обратного вызова.

map()

Функция map() практически идентична функции forEach() . Единственное отличие состоит в том, что map() возвращает массив, содержащий значения, возвращаемые функцией обратного вызова. Например, следующий код использует map() для вычисления квадратного корня каждого элемента во входном массиве. Результаты затем возвращаются в виде массива и отображаются. Также обратите внимание, что дополнительные функции массива совместимы со встроенными функциями JavaScript, такими как Math.sqrt() .

 var sqrts = [1, 4, 9, 16, 25].map(Math.sqrt); console.log(sqrts); // displays "[1, 2, 3, 4, 5]" 

filter()

Как и forEach() и map() , метод filter() принимает функцию обратного вызова и необязательное this значение. И, подобно map() , filter() возвращает массив значений на основе возвращаемого значения функции обратного вызова. Разница в том, что функция обратного вызова filter() должна возвращать логическое значение. Если возвращаемое значение равно true, то элемент массива добавляется в массив результатов. Например, следующий код удаляет все элементы из исходного массива, которые не начинаются с буквы x. В этом примере регулярное выражение (переданное как значение this ) проверяется для каждого элемента массива.

 ["x", "abc", "x1", "xyz"].filter(RegExp.prototype.test, /^x/); 

every() и some()

Функции every() и some() также запускают функцию обратного вызова для каждого элемента массива. Если каждая функция обратного вызова возвращает true , то every() возвращает true , иначе она возвращает false . Аналогично, some() возвращает true если хотя бы одна функция обратного вызова возвращает true . В следующем примере every() и some() используются для проверки, если элементы массива меньше пяти. В этом случае every() возвращает false поскольку последний элемент равен пяти. Однако some() возвращает true потому что хотя бы один элемент меньше пяти. Обратите внимание, что аргументы index и array существуют, но были исключены из функции обратного вызова, потому что они не нужны в этом примере.

 var foo = [1, 2, 3, 4, 5]; var every = foo.every(function(element) { return element < 5; }); var some = foo.some(function(element) { return element < 5; }); // every = false, some = true 

reduceRight() и reduceRight()

Метод reduce() обрабатывает каждый элемент массива, начиная с самого начала, и вычисляет одно значение. reduce() принимает в качестве аргументов функцию обратного вызова и необязательное начальное значение. Если начальное значение отсутствует, то используется первый элемент массива. Функция обратного вызова redu reduce() отличается от других функций обратного вызова, которые мы видели до сих пор, так как она принимает четыре аргумента — предыдущее значение, текущее значение, индекс и массив.

Типичным примером операции приведения является суммирование всех значений массива. Следующий пример делает именно это. При первом вызове функции обратного вызова previous равен единице, а current равен двум. В последующих вызовах сумма накапливается до конечного значения 15.

 var sum = [1, 2, 3, 4, 5].reduce(function(previous, current, index, array) { return previous + current; }); // sum = 15 

Метод reduceRight() работает так же, как и reduceRight() , за исключением того, что обработка начинается в конце массива и перемещается в начало.

indexOf() и lastIndexOf()

Метод indexOf() ищет в массиве определенный элемент и возвращает индекс первого совпадения. Если совпадений не найдено, indexOf() возвращает -1. indexOf() принимает элемент для поиска в качестве первого аргумента. Второй необязательный аргумент используется для указания начального индекса поиска. Например, следующий код находит первые два вхождения буквы z в массиве. Чтобы найти второе вхождение, мы просто находим первое вхождение, а затем снова начинаем поиск после него.

 var foo = ["a", "z", "b", "z"]; var first = foo.indexOf("z"); var second = foo.indexOf("z", first + 1); // first = 1, second = 3 

Метод lastIndexOf() работает точно так же, за исключением того, что он начинает поиск с конца массива.

Вывод

Использование дополнительных функций массива может привести к чистому, лаконичному коду. К сожалению, некоторые старые браузеры не поддерживают эти методы. Однако вы можете обнаружить эти методы, Array.prototype объект Array.prototype (т.е. Array.prototype.forEach ). Если метод отсутствует, вы можете легко предоставить собственную реализацию.