Для чего нужен метод reduce javascript
Перейти к содержимому

Для чего нужен метод reduce javascript

  • автор:

Что делает метод reduce js?

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

// Корзина товаров на сайте const cart = [ name:'Milk', price: 25>, name:'Bread', price: 12>, name:'Eggs', price: 17>, ]; // Как просто посчитать сумму всей корзины? Применим reduce(): const cartTotal = cart.reduce((totalSumm, item) =>  totalSumm += item.price; // мы всегда должны возвращать аккумулятор как результат работы над каждым элементом. return totalSumm; // 0 - здесь, это начальное значение totalSumm. >, 0); console.log(cartTotal); // -> 54 

Array.prototype.reduce()

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

Интерактивный пример

Синтаксис

array.reduce(callback[, initialValue])

Параметры

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

Аккумулятор, аккумулирующий значение, которое возвращает функция callback после посещения очередного элемента, либо значение initialValue , если оно предоставлено (смотрите пояснения ниже).

Текущий обрабатываемый элемент массива.

Индекс текущего обрабатываемого элемента массива.

Массив, для которого была вызвана функция reduce .

Необязательный параметр. Объект, используемый в качестве первого аргумента при первом вызове функции callback .

Описание

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

При первом вызове функции, параметры accumulator и currentValue могут принимать одно из двух значений. Если при вызове reduce() передан аргумент initialValue , то значение accumulator будет равным значению initialValue , а значение currentValue будет равным первому значению в массиве. Если аргумент initialValue не задан, то значение accumulator будет равным первому значению в массиве, а значение currentValue будет равным второму значению в массиве.

Если массив пустой и аргумент initialValue не указан, будет брошено исключение TypeError . Если массив состоит только из одного элемента (независимо от его положения в массиве) и аргумент initialValue не указан, или если аргумент initialValue указан, но массив пустой, то будет возвращено одно это значение, без вызова функции callback .

Предположим, что reduce() используется следующим образом:

[0, 1, 2, 3, 4].reduce(function (previousValue, currentValue, index, array)  return previousValue + currentValue; >); 

Колбэк-функция будет вызвана четыре раза, аргументы и возвращаемое значение при каждом вызове будут следующими:

previousValue currentValue index array возвращаемое значение
первый вызов 0 1 1 [0, 1, 2, 3, 4] 1
второй вызов 1 2 2 [0, 1, 2, 3, 4] 3
третий вызов 3 3 3 [0, 1, 2, 3, 4] 6
четвёртый вызов 6 4 4 [0, 1, 2, 3, 4] 10

Значение, возвращённое методом reduce() будет равным последнему результату выполнения колбэк-функции — 10 .

Если же вы зададите начальное значение initialValue , результат будет выглядеть так:

[0, 1, 2, 3, 4].reduce(function (accumulator, currentValue, index, array)  return accumulator + currentValue; >, 10); 
accumulator currentValue index array возвращаемое значение
первый вызов 10 0 0 [0, 1, 2, 3, 4] 10
второй вызов 10 1 1 [0, 1, 2, 3, 4] 11
третий вызов 11 2 2 [0, 1, 2, 3, 4] 13
четвёртый вызов 13 3 3 [0, 1, 2, 3, 4] 16
пятый вызов 16 4 4 [0, 1, 2, 3, 4] 20

Значение, возвращённое методом reduce() на этот раз, конечно же, будет равным 20 .

Примеры

Суммирование всех значений в массиве

var total = [0, 1, 2, 3].reduce(function (a, b)  return a + b; >); // total == 6 

Суммирование значений в массиве объектов

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

var initialValue = 0; var sum = [ x: 1 >,  x: 2 >,  x: 3 >].reduce(function ( accumulator, currentValue, )  return accumulator + currentValue.x; >, initialValue); // sum == 6 

Тоже самое, но со стрелочной функцией:

var initialValue = 0; var sum = [ x: 1 >,  x: 2 >,  x: 3 >].reduce( (accumulator, currentValue) => accumulator + currentValue.x, initialValue, ); // sum == 6 

Разворачивание массива массивов

var flattened = [ [0, 1], [2, 3], [4, 5], ].reduce(function (a, b)  return a.concat(b); >); // flattened равен [0, 1, 2, 3, 4, 5] 

Пример: склеивание массивов, содержащихся в объектах массива, с использованием оператора расширения и initialValue

// friends - список из объектов(друзей) // где поле "books" - список любимых книг друга var friends = [  name: "Anna", books: ["Bible", "Harry Potter"], age: 21 >,  name: "Bob", books: ["War and peace", "Romeo and Juliet"], age: 26 >,  name: "Alice", books: ["The Lord of the Rings", "The Shining"], age: 18 >, ]; // allbooks - список, который будет содержать все книги друзей + // дополнительный список указанный в initialValue var allbooks = friends.reduce( function (prev, curr)  return [. prev, . curr.books]; >, ["Alphabet"], ); // allbooks = ["Alphabet", "Bible", "Harry Potter", "War and peace", // "Romeo and Juliet", "The Lord of the Rings", "The Shining"] 

Полифил

Метод Array.prototype.reduce() был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать reduce() в реализациях, которые не поддерживают этот метод.

// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.21 // Ссылка (en): http://es5.github.io/#x15.4.4.21 // Ссылка (ru): http://es5.javascript.ru/x15.4.html#x15.4.4.21 if (!Array.prototype.reduce)  Array.prototype.reduce = function (callback /*, initialValue*/)  "use strict"; if (this == null)  throw new TypeError("Array.prototype.reduce called on null or undefined"); > if (typeof callback !== "function")  throw new TypeError(callback + " is not a function"); > var t = Object(this), len = t.length >>> 0, k = 0, value; if (arguments.length >= 2)  value = arguments[1]; > else  while (k  len && !(k in t))  k++; > if (k >= len)  throw new TypeError("Reduce of empty array with no initial value"); > value = t[k++]; > for (; k  len; k++)  if (k in t)  value = callback(value, t[k], k, t); > > return value; >; > 

Спецификации

Specification
ECMAScript Language Specification
# sec-array.prototype.reduce

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

Метод reduce

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

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

Промежуточный результат — это переменная, в которой будет накапливаться то значение, которое вернет метод reduce , когда переберет все элементы массива. К примеру, туда последовательно можно накапливать сумму элементов массива: сначала положить первый элемент, при следующем проходе цикла уже сумму первого элемента и второго, при следующем проходе — сумму первого, второго и третьего. И так, пока массив не закончится. Функция, которую принимает reduce , должна возвращать новое значение промежуточного результата.

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

Синтаксис

массив.reduce(function(промежуточный результат, элемент, индекс, массив) < return новый промежуточный результат; >, начальное значение);

Пример

Найдем сумму элементов массива:

let arr = [1, 2, 3, 4, 5, 6]; let res = arr.reduce(function(sum, elem) < return sum + elem; >, 0); console.log(res);

Результат выполнения кода:

Пример

Давайте найдем сумму всех положительных чисел массива:

let arr = [1, -2, -3, 4, 5, -6]; let res = arr.reduce(function(sum, elem) < if (elem >= 0) < return sum + elem; >else < return sum; >>); console.log(res);

Результат выполнения кода:

Смотрите также

  • метод reduceRight ,
    выполняющий похожую операцию
  • метод filter ,
    который позволяет фильтровать элементы массива
  • методы map и forEach ,
    которые позволяют применить функцию к каждому элементу массива
  • методы some и every ,
    выполняющие проверку массива

reduce() JS — как работает и когда его нужно применять

Данный метод наверное наиболее сложный из методов массивов. Давайте рассмотрим как с ним работать и разберем несколько примеров где он может применяться.

Метод reduce() выполняет заданную функцию к каждому элементу массива и возвращает «аккумулированный» результат.

array.reduce(function(total, currentValue, currentIndex, arr))

total — начальное значение или ранее возвращенное значение (из предыдущей итерации).
currentValue — текущее значение массива
currentIndex — индекс текущего элемента
arr — проходимый массив

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

Наиболее наглядный пример — это подсчет суммы значений элементов массива. Например, у нас есть такой массив:

const salary = [1000, 1200, 900, 1800]; const sum = salary.reduce((total, currentItem) => < total += currentItem; return total; >, 0) // 0 - это начальное значение, тут мы могли бы указать другое число console.log('sum', sum); // 4900

Рассмотрим другой пример. У нас есть массив пользователей. Каждый пользователь это обьект. У каждого пользователя есть имя, возраст и размер компенсации. Нам нужно высчитать среднюю заработную плату:

const users = [ < name: 'John', age: 32, salary: 1500 >, < name: 'Mike', age: 25, salary: 1200 >, < name: 'Pieter', age: 27, salary: 1400 >, < name: 'Jim', age: 22, salary: 1800 >]; const averageSalary = users.reduce((total, user) => < total += user.salary/users.length; return total; >, 0); console.log('Average Salary', averageSalary); // 1475

Если в примере выше у вас users это не массив, а объект и задача та же — посчитать среднюю з/п, тогда мы можем сделать так:

const users = < 0: < name: 'John', age: 32, salary: 1500 >, 1: < name: 'Mike', age: 25, salary: 1200 >, 2: < name: 'Pieter', age: 27, salary: 1400 >, 3: < name: 'Jim', age: 22, salary: 1800 >> // Определяем количество элементов в объекте const userObjLength = Object.keys(users).length; const averageSalary = Object.keys(users).reduce((total, key) => < // В [key] у нас попадает ключ с обьекта users (от 0 до 3) total += users[key].salary/userObjLength; return total; >, 0); console.log('Average Salary', averageSalary); // 1475

Преобразование массива в объект с помощью reduce

В двух последних примерах у нас есть массив users и есть объект users . А что если нам нужно преобразовать массив в объект? Для этого мы также можем воспользоваться методом reduce()

const users = [ < name: 'John', age: 32, salary: 1500 >, < name: 'Mike', age: 25, salary: 1200 >, < name: 'Pieter', age: 27, salary: 1400 >, < name: 'Jim', age: 22, salary: 1800 >] const usersObj = users.reduce((acc, user, index) => < acc[index] = user return acc; // Начальное значение <>>, <>); console.log('New Object', usersObj);

Так как на выходе нам нужен объект, мы вторым параметром в метод reduce передаем пустой объект и дальше на каждой итерации добавляем ему новую пару «ключ — значение». В качестве ключа у нас выступает индекс текущего элемента в массиве.

Пишем свой метод reduce на JavaScript

Мы разберем два примера: простой и более сложный, в котором будут обрабатываться ошибки и проверяться условия.

Array.prototype.customReduce = function(callback, result) < let i = 0; // Проверяем если кол-во аргументов меньше 2, значит не передано дефолтное значение if (arguments.length < 2) < i = 1; // В данном случае this указывает на итерируемый массив result = this[0] >for (; i < this.length; i++) < result = callback(result, this[i], i, this); >return result; >

Мы сразу добавили данный метод к прототипу массива, чтобы его можно было легко вызвать. Теперь проверим выдаст ли он нам такой же результат, как был в самом первом примере этого поста:

const salary = [1000, 1200, 900, 1800]; const sum = salary.customReduce((total, currentItem) => < total += currentItem; return total; >, 0); console.log('sum', sum); // 4900

Теперь давайте рассмотрим более сложный вариант с дополнительными проверками:

Array.prototype.customReduce = function(callBack, initialValue) < // Проверяем не пустой ли массив и задано ли дефолтное значение if (!this.length && initialValue === undefined) throw new TypeError('Массив пустой. Невозможно к нему применить данный метод'); // Если дефолтное значение задано, то присваиваем его к accumulator, который в итоге будем возвращать let accumulator = initialValue; let index = 0; if (initialValue === undefined) < // Если нет дефолтного значения, тогда accumulator будет присваиваться значение первого элемента массива accumulator = this[0]; index = 1; >// В цикле проходимся по нашему массиву и передаем наш callback, который нужно выполнить для каждого элемента массива for (; index < this.length; index++) < // Как мы помним метод reduce принимает 4 параметра (см начало поста) // Поэтому мы в наш callback передаем такие же 4 параметра accumulator = callBack(accumulator, this[index], index, this); >return accumulator; >

Если остались вопросы — пишите в комментарии.

Ваши вопросы и комментарии:

Свежие записи

  • MySQL IS NULL — проверка поля на NULL
  • MySQL LIKE — поиск по паттерну
  • Between MySQL — оператор для выборки по диапазону значений
  • MySQL IN и NOT IN — несколько условий
  • MySQL WHERE — синтаксис и примеры

Копирование материалов разрешено только с ссылкой на источник Web-Dev.guru
2023 © Все права защищены.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *