Функции массивов в JavaScript Map, Reduce, Filter, ForEach, Every, Find, Some, IndexOf, Includes, Flat, At, Concat, Entries

Map, Reduce и Filter — все это методы массивов в JavaScript. Каждый из них будет перебирать массив и выполнять преобразование или вычисление.

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

Краткое резюме использования map, reduce и filter данных функций, проиллюстрированный @steveluscher

//Map/filter/reduce in a tweet:
items.map([?, ?, ?], cook)
=> [?, ?, ?]

items.filter([?, ?, ?], isVegetarian)
=> [?, ?]

items.reduce([?, ?], eat)
=> ?
//— Steven Luscher (@steveluscher) June 10, 2016

Map

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

var new_array = arr.map(function callback(element, index, array) {
    // Return value for new_array
}[, thisArg])

В обратном вызове callback требуется только элемент element массива. Обычно какое-то действие выполняется со значением, а затем возвращается новое значение.

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

const numbers = [1, 4, 9];
const doubles = numbers.map((num) => num * 2);
// теперь doubles равен [2, 8, 18], а numbers всё ещё равен [1, 4, 9]

Filter

Метод filter() берет каждый элемент массива и применяет к нему условный оператор. Если это условное выражение возвращает true, элемент помещается в выходной массив. Если условие возвращает false, элемент не помещается в выходной массив

var new_array = arr.filter(function callback(element, index, array) {
    // Return true or false
}[, thisArg])

Синтаксис filter аналогичен map, за исключением того, что функция обратного вызова callback должна возвращать true, чтобы сохранить элемент, или false в противном случае. В обратном вызове обязателен только элемент element.

В следующем примере нечетные числа «отфильтровываются», оставляя только четные числа

const numbers = [1, 2, 3, 4];
const evens = numbers.filter(item => item % 2 === 0);
console.log(evens); // [2, 4]

В следующем примере filter() используется для получения всех учащихся, чьи оценки больше или равны 90

const students = [
  { name: 'Quincy', grade: 96 },
  { name: 'Jason', grade: 84 },
  { name: 'Alexis', grade: 100 },
  { name: 'Sam', grade: 65 },
  { name: 'Katie', grade: 90 }
];

const studentGrades = students.filter(student => student.grade >= 90);
return studentGrades; // [ { name: 'Quincy', grade: 96 }, { name: 'Alexis', grade: 100 }, { name: 'Katie', grade: 90 } ]

Reduce

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

arr.reduce(callback[, initialValue])

Аргумент обратного вызова callback — это функция, которая будет вызываться один раз для каждого элемента массива. Эта функция принимает четыре аргумента, но часто используются только первые два.

  • accumulator — возвращаемое значение предыдущей итерации
  • currentValue — текущий элемент в массиве
  • index — индекс текущего элемента
  • array — исходный массив, для которого было вызвано сокращение
  • initialValue — исходный массив, для которого было вызвано сокращение является необязательным. Если указано, оно будет использоваться в качестве начального значения аккумулятора при первом вызове функции обратного вызова.

В следующем примере каждое число складывается вместе в массиве чисел

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);
console.log(sum); // 10

В следующем примере метод reduce() используется для преобразования массива строк в один объект, показывающий, сколько раз каждая строка встречается в массиве. Обратите внимание, что этот вызов для сокращения передает пустой объект {} в качестве параметра initialValue

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

var pets = ['dog', 'chicken', 'cat', 'dog', 'chicken', 'chicken', 'rabbit'];

var petCounts = pets.reduce(function(obj, pet){
    if (!obj[pet]) {
        obj[pet] = 1;
    } else {
        obj[pet]++;
    }
    return obj;
}, {});

console.log(petCounts); 

/*
Output:
 { 
    dog: 2, 
    chicken: 3, 
    cat: 1, 
    rabbit: 1 
 }
 */

ForEach

Метод массива forEach() позволяет применить колбэк-функцию ко всем элементам массива. Можно использовать вместо классического цикла for. В отличие от него forEach() выглядит более читабельным и понятным.

arr.forEach(function callback(currentValue, index, array) {
    //your iterator
}[, thisArg]);

пример использования

const numbers = [1, 2, 3, 4]

numbers.forEach((num) => {
  const square = num * num
  console.log('Квадрат числа равен: ' + square)
})
//Выведет
/*
Квадрат числа равен: 1
Квадрат числа равен: 4
Квадрат числа равен: 9
Квадрат числа равен: 16
*/

Важно знать, какие параметры принимает колбэк. Всего их три:

  • item — элемент массива в текущей итерации;
  • index — индекс текущего элемента;
  • arr — сам массив, который мы перебираем.

Every

Метод every() проверяет, удовлетворяют ли все элементы массива условию, заданному в передаваемой функции

arr.every(callback[, thisArg])

callback  — функция проверки каждого элемента, принимает три аргумента:

  • currentValue Текущий обрабатываемый элемент в массиве.
  • index Индекс текущего обрабатываемого элемента в массиве.
  • array Массив, по которому осуществляется проход.

thisArg — необязательный параметр. Значение, используемое в качестве this при выполнении функции callback.

Метод every вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве до тех пор, пока не найдет такой, для которого callback вернет ложное значение (значение, становящееся равным false при приведении его к типу Boolean)

Если такой элемент найден, метод every немедленно вернёт false. В противном случае, если callback вернёт true для всех элементов массива, метод every вернёт true.

Функция callback вызывается только для индексов массива, имеющих присвоенные значения и она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались.

Метод every не изменяет массив, для которого он был вызван.

Следующий пример проверяет, являются ли все элементы массива числами, большими 10

function isBigEnough(element, index, array) {
  return element >= 10;
}
var passed = [12, 5, 8, 130, 44].every(isBigEnough);
// passed равен false
passed = [12, 54, 18, 130, 44].every(isBigEnough);
// passed равен true

Some

Метод some() проверяет, удовлетворяет ли хоть какой-нибудь элемент массива условию, заданному в передаваемой функции

arr.some(callback[, thisArg])
  • callback — функция проверки каждого элемента.
  • thisArg — необязательный параметр. Значение, используемое в качестве this при выполнении функции callback.

Метод some вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве до тех пор, пока не найдет такой, для которого callback вернет истинное значение (значение, становящееся равным true при приведении его к типу Boolean). Если такой элемент найден, метод some немедленно вернёт true. В противном случае, если callback вернёт false для всех элементов массива, метод some вернёт false. Функция callback вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались.

Функция callback вызывается с тремя аргументами: значением элемента, индексом элемента и массивом, по которому осуществляется проход.

Метод some не изменяет массив, для которого он был вызван.

Следующий пример проверяет, есть ли в массиве какой-нибудь элемент, больший 10

function isBigEnough(element, index, array) {
  return element >= 10;
}
var passed = [2, 5, 8, 1, 4].some(isBigEnough);
// passed равен false
passed = [12, 5, 8, 1, 4].some(isBigEnough);
// passed равен true

Find

Метод массива find() вернёт первый найденный в массиве элемент, который подходит под условие в переданной колбэк-функции. Если в массиве не найдётся ни одного подходящего элемента, то вернётся значение undefined

function isMyFavoriteHobby(element, index, array) {
  return element === 'смотреть сериальчики'
}

const currentToDoList = [
  'смотреть сериальчики',
  'читать книгу',
  'пить кофе',
  'гладить кота',
  'гулять',
]
const tomorrowToDoList = [
  'читать книгу',
  'пить кофе',
  'гладить кота',
  'гулять',
]

console.log(currentToDoList.find(isMyFavoriteHobby))
// 'смотреть сериальчики'

console.log(tomorrowToDoList.find(isMyFavoriteHobby))
// undefined, не найдено

В метод find() необходимо передать аргументом функцию. Функция должна возвращать булевое значение true или falsefind() вернёт первый элемент, на котором переданная функция-колбэк вернула true.

Чтобы получить необходимый элемент, нужно определить условие поиска. В этом нам поможет функция-предикат. Предикат — это функция, которая возвращает булевое значение.

От результата выполнения функции зависит, вернёт ли find() подходящий элемент:

  • true — элемент проходит проверку.
  • false — элемент не проходит проверку.

IndexOf

Метод findIndex() возвращает индекс первого найденного в массиве элемента, который подходит под условие переданной функции. Если же ни одного подходящего элемента не найдётся, то метод вернёт -1

Если вам нужно получить элемент, а не его индекс, то используйте метод find(). А если необходимо проверить наличие чего-либо в массиве, то сначала обратите внимание на метод includes().

Напишем код, который позволит найти человека в списке гостей мероприятия. Для этого определим функцию, которая будет получать имя из массива участников и сверять его с константой guestName. Затем передадим эту функцию в метод findIndex()

function isWantedGuest(element, index, array) {
  return element === 'Лиза'
}

const partyGuests = [
  'Даня',
  'Саша',
  'Юля',
  'Лиза',
  'Егор'
]

const meetingGuests = [
  'Даня',
  'Егор',
  'Арсений'
]

console.log(partyGuests.findIndex(isWantedGuest))
// 3 (так как partyGuests[3] -> 'Лиза')

console.log(meetingGuests.findIndex(isWantedGuest))
// -1 (совпадений нет)

Метод findIndex() обходит массив и возвращает индекс первого элемента, который подходит под условие функции-предиката. Если ничего не подошло, то он возвращает -1.

Предикативная функция (функция-предикат) — это функция, которая проверяет значение на соответствие какому-то условию, а затем возвращает true или false.

Функция, которую мы передаём в метод findIndex(), может принимать три параметра:

  • element — элемент массива в текущей итерации;
  • index — индекс текущего элемента;
  • array — сам массив, который перебираем.

Includes

Метод includes() определяет, содержит ли массив определённый элемент, возвращая в зависимости от этого true или false

arr.includes(searchElement[, fromIndex = 0])

В следующем примере показывается поиск значений в массиве

const array1 = [1, 2, 3];

console.log(array1.includes(2));
// выведет: true

const pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// выведет: true

console.log(pets.includes('at'));
// выведет: false
  • searchElement — искомый элемент
  • fromIndex — необязательныйПозиция в массиве, с которой начинать поиск элемента  searchElement. При отрицательных значениях поиск производится начиная с индекса array.length + fromIndex по возрастанию. Значение по умолчанию равно 0.

Flat

Метод flat() возвращает новый массив и уменьшает вложенность массива на заданное количество уровней

Пример использования

const nested = [
  'первый уровень',
  'первый уровень',
  [
    'второй уровень',
    'второй уровень',
    [
      'третий уровень',
      'третий уровень'
    ]
  ]
]
//Вызовем метод flat() без аргументов:
const flat = nested.flat()
console.log(flat)
//Это выведет
/*
[
  'первый уровень',
  'первый уровень',
  'второй уровень',
  'второй уровень',
  [
    'третий уровень',
    'третий уровень'
  ]
]
*/

At

Метод at() принимает значение в виде целого числа и возвращает элемент массива с данным индексом. В качестве аргумента метод принимает положительные и отрицательные числа. При отрицательном значении отсчёт происходит с конца массива.

Получение элементов массива с помощью квадратных скобок по-прежнему остаётся корректным способом. Например, array[0] вернёт первый элемент. Однако, при работе с элементами в конце массива больше нет необходимости прибегать к array.length. Например, для получения последнего элемента, вместо array[array.length-1] можно вызвать array.at(-1).
const array1 = [5, 12, 8, 130, 44];

let index = 2;

console.log(`Using an index of ${index} the item returned is ${array1.at(index)}`);
console.log(`Using an index of ${index} the item returned is ${array1.at(index)}`);
// вывод: "Using an index of 2 the item returned is 8"
index = -2;
console.log(`Using an index of ${index} item returned is ${array1.at(index)}`);
// вывод: "Using an index of -2 item returned is 130"
  • index — ндекс (позиция) элемента возвращаемого элемента массива. При передаче отрицательного индекса применяется относительная индексация с конца массива; например, при использовании отрицательного числа, возвращаемый элемент находится путём обратного отсчёта с конца массива.

Concat

Метод concat() возвращает новый массив, состоящий из массива, на котором он был вызван, соединённого с другими массивами и/или значениями, переданными в качестве аргументов.

var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])

Пример

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);
// выведет: Array ["a", "b", "c", "d", "e", "f"]
  • valueN — массивы и/или значения, соединяемые в новый массив.

Entries

Метод entries() возвращает новый объект итератора массива Array Iterator, содержащий пары ключ / значение для каждого индекса в массиве.

var arr = ['a', 'b', 'c'];
var eArr = arr.entries();

console.log(eArr.next().value); // [0, 'a']
console.log(eArr.next().value); // [1, 'b']
console.log(eArr.next().value); // [2, 'c']

Заключение

Дополнительно про функции массивов можно почитать по ссылке.

Пожалуйста, оцените материал

Функции массивов в JavaScript Map, Reduce, Filter, ForEach, Every, Find, Some, IndexOf, Includes, Flat, At, Concat, Entries