Метод reduce в JavaScript


reduce - это метод, который может быть трудным для понимания, особенно со всеми расплывчатыми объяснениями, которые можно найти в интернете. Есть много преимуществ в понимании reduce поскольку он часто используется в управлении состоянием.

Синтаксис метода reduce массива в JavaScript:

arr.reduce(callback, initialValue); 
Терминология

reduce идет с некоторой терминологией, такой как редуктор и аккумулятор. accumulator - это значение, которым мы заканчиваем, а reducer - это то, что мы будем выполнять, чтобы получить одно значение.

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

Возьмите следующий классический пример:

const value = 0; 

const numbers = [5, 10, 15];

for(let i = 0; i < numbers.length; i++) {
  value += numbers[i];
} 
Вышесказанное даст нам 30 (5 + 10 + 15). Это прекрасно работает, но мы можем сделать это с помощью reduce что избавит нас от изменения нашей переменной value. Приведенный ниже код также выведет 30, но не изменит нашу переменную value (которую мы теперь назвали initialValue)

/* первоначальное значение*/
const initialValue = 0;

/* массив */
const numbers = [5, 10, 15];

/* метод */
const reducer = (accumulator, item) => {
  return accumulator + item;
};

/* получение */
const total = numbers.reduce(reducer, initialValue)
 
Приведенный выше код может показаться немного запутанным, но под капотом не происходит никакой магии. Давайте добавим console.log в наш метод reducer, который будет выводить аргументы accumulator и item.

Что у нас получилось в результате:



Итак, первое, что мы заметили - наш метод вызывается 3 раза, потому что в нашем массиве 3 значения. Наш аккумулятор начинается с 0, который является нашим initialValue мы передали для reduce. При каждом вызове функции item добавляется в accumulator . Последний вызов метода имеет значение accumulator 15 а item 15, 15 + 15 дает 30 что является нашим окончательным значением. Помните, что метод reduce возвращает accumulator плюс item .

Итак, это простой пример того, как вы будете использовать reduce, теперь давайте рассмотрим более сложный пример. Сглаживание массива с помощью Reduce

Допустим, у нас есть следующий массив:

const numArray = [1, 2, [3, 10, [11, 12]], [1, 2, [3, 4]], 5, 6];
 
И скажем по какой-то сумасшедшей причине, JavaScript удалил метод flat поэтому мы должны сгладить этот массив самостоятельно.

Поэтому мы напишем функцию для выравнивания любого массива независимо от того, насколько глубоко вложены массивы:

function flattenArray(data) {
  // наше начальное значение на этот раз-пустой массив
  const initialValue = [];

  // call reduce on our data
  return data.reduce((total, value) => {
    // если значение является массивом, то рекурсивный вызов уменьшает
    // если значение не является массивом, то просто объедините наше значение
    return total.concat(Array.isArray(value) ? flattenArray(value) : value);
  }, initialValue);
}
Если мы передадим наш numArray этому, то получим следующее:



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

Давайте рассмотрим еще один пример - изменение структуры объекта

Итак, с выходом новой игры Pokemon, давайте представим, что у нас есть сервер, который отправляет нам массив объектов Pokemon:

const pokemon = [
  { name: "charmander", type: "fire" },
  { name: "squirtle", type: "water" },
  { name: "bulbasaur", type: "grass" }
]
Мы хотим изменить этот объект так:

const pokemonModified = {
  charmander: { type: "fire" },
  squirtle: { type: "water" },
  bulbasaur: { type: "grass" }
};
Чтобы получить желаемый результат, мы делаем следующее:

const getMapFromArray = data =>
  data.reduce((acc, item) => {
    // add object key to our object i.e. charmander: { type: 'water' }
    acc[item.name] = { type: item.type };
    return acc;
  }, {});
Если мы вызываем наш метод так:

getMapFromArray (pokemon)
то получаем желаемый результат:



Вот и все! Надеюсь, вы узнали, как работает метод reduce.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, JavaScript, методы




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




Неочевидный взлом сайта
Урок 1. Введение в WPF, основные концепции
Непрерывная передача данных с EventSource