Map, Filter и Reduce в JavaScript


Map, Filter и Reduce в JavaScript

Синтаксис для map показан ниже.

array.map(function(currentValue, index, arr), thisValue)
// return element for newArray, after executing something
Вход в полноэкранный режим Выйти из полноэкранного режима

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

Под капотом, map передает три аргумента в обратный вызов:

  1. текущий элемент в массиве
  2. индекс массива текущего элемента
  3. весь массив, для которого вы вызвали map.

Давайте посмотрим на некоторый код

map в примере

// Durations are in minutes 
const tasks = [
  {
    'name'     : 'Write for Learning',
    'duration' : 120
  },
  {
    'name'     : 'Work out',
    'duration' : 60
  },
  {
    'name'     : 'Watching Movie',
    'duration' : 60
  }
];
Вход в полноэкранный режим Выйти из полноэкранного режима

Допустим, мы хотим создать новый массив, содержащий только имя каждой задачи, чтобы мы могли просмотреть все, что мы сделали сегодня. Используя цикл for, мы напишем что-то вроде этого:

const task_names = [];
for (let i = 0; i < tasks.length; i +=1){
    task_names.push(tasks[i].name)
}
console.log(task_names) // [ 'Write for Learning', 'Work out', 'Watching Movie' ]
Войти в полноэкранный режим Выйти из полноэкранного режима

JavaScript также предлагает цикл forEach. Он функционирует так же, как цикл for, но управляет всеми сложностями, связанными с проверкой индекса цикла на длину массива:

const task_names = [];

tasks.forEach(function (task) {
    task_names.push(task.name);    
});

console.log(task_names) // [ 'Write for Learning', 'Work out', 'Watching Movie' ]
Вход в полноэкранный режим Выход из полноэкранного режима

Используя map, мы можем просто написать:

const task_names = tasks.map(function (task, index, array) {
    return task.name; 
});
console.log(task_names) // [ 'Write for Learning', 'Work out', 'Watching Movie' ]
Войти в полноэкранный режим Выйти из полноэкранного режима

Еще более лаконичным способом написания map в современном JavaScript является использование стрелочных функций

const task_names = tasks.map(task => task.name)

console.log(task_names) // [ 'Write for Learning', 'Work out', 'Watching Movie' ]
Войти в полноэкранный режим Выйти из полноэкранного режима

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

let map = function (array, callback) {
  const new_array = [];

  array.forEach(function (element, index, array) {
    new_array.push(callback(element));
  });

  return new_array;
};
Вход в полноэкранный режим Выход из полноэкранного режима

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

Подробнее

Фильтр
Делает именно то, что звучит: Берет массив и отфильтровывает ненужные элементы.

Синтаксис для filter следующий:

array.filter(function(currentValue, index, arr), thisValue)
// return element for newArray, if true
Войти в полноэкранный режим Выйти из полноэкранного режима
const words = ['Python', 'Javascript', 'Go', 'Java', 'PHP', 'Ruby'];
const result = words.filter(word => word.length < 8);
console.log(result);
Войти в полноэкранный режим Выйти из полноэкранного режима

Используя forEach, мы бы написали:

const difficult_tasks = [];

tasks.forEach(function (task) {
    if (task.duration >= 120) {
        difficult_tasks.push(task);
    }
});
console.log(difficult_tasks)
Войти в полноэкранный режим Выйти из полноэкранного режима

Используя filter, мы можем просто написать:

const difficult_tasks = tasks.filter((task) => task.duration >= 120 );
console.log(difficult_tasks)
Войти в полноэкранный режим Выйти из полноэкранного режима

  • избежать изменения массива внутри цикла forEach или for
  • присваивать его результат непосредственно новой переменной, а не заталкивать в массив, который мы определили в другом месте.

Уменьшить

уменьшить на практике

let numbers = [1, 2, 3, 4, 5],
    total = 0;

numbers.forEach(function (number) {
    total += number;
});
console.log(total); // 15
Вход в полноэкранный режим Выйти из полноэкранного режима

Хотя это не плохой вариант использования forEach, reduce все же имеет преимущество, позволяя нам избежать мутации. Используя reduce, мы бы написали:

const total = [1, 2, 3, 4, 5].reduce(function (previous, current) {
    return previous + current;
}, 0);
console.log(total); // 15
Войти в полноэкранный режим Выйти из полноэкранного режима

Сначала мы вызываем reduce для нашего списка чисел. Мы передаем ему обратный вызов, который принимает в качестве аргументов предыдущее и текущее значения и возвращает результат их сложения. Поскольку мы передали 0 в качестве второго аргумента reduce, на первой итерации он будет использовать это значение в качестве previous.

С помощью стрелочных функций мы могли бы написать это следующим образом:

const total = [1, 2, 3, 4, 5].reduce((previous, current) => previous+current),0;
console.log(total) // 15
Войти в полноэкранный режим Выйти из полноэкранного режима

Если мы сделаем шаг за шагом, это будет выглядеть следующим образом:

Другой пример

let num1 = [2, 3, 4, 5, 6, 7];
let num4 = num1.reduce(sum)
         function sum(total, value){
             return total + value;
         }
document.getElementById("demo").innerHTML = num4; // 27
Вход в полноэкранный режим Выход из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий