Большая часть Фазы 1 буткемпа Flatiron Software Development была довольно гладкой (но в то же время веселой и сложной). Но по причинам, которые до сих пор мне неясны, метод .reduce() поставил меня в тупик дольше всего, намного. Я совершил ошибку, пройдя модули курса, не потратив времени на то, чтобы полностью их понять; затем, как только я наткнулся на задание, в котором меня просили создать метод .reduce() с нуля, мне пришлось вернуться и на самом деле копаться в том, чего я раньше не понимал. Промедление никогда не окупается!
Теперь, когда я, наконец, освоил метод .reduce(), объяснение его своими словами поможет закрепить его в моем сознании и, надеюсь, даст другим ясность, которая дается легче, чем мне.
Для начала давайте рассмотрим концепцию уменьшения массива значений и то, как мы можем закодировать это вручную.
const array = [1, 2, 3, 4]; let finalValue = 0; function addArray(array) { for (const element of array) { finalValue += element; } return finalValue; } //Function call addArray(array) //=>10
Мы перебираем каждое значение в массиве для накопления и возврата одного значения. Эта конкретная функция просто складывает все элементы массива вместе, чтобы получить окончательную сумму.
Но что, если мы хотим сделать что-то более сложное с каждым элементом массива передсверткой? Нам придется написать другую функцию!
const array = [1, 2, 3, 4]; let finalValue = 0; function multiplyAndAddArray(array) { for (const element of array) { finalValue += (element * 2); } return finalValue; } //Function call multiplyAndAddArray(array) //=>20
Одна концепция, которую я постоянно встречал на этапе 1, — это понятие «абстракции»: обобщенный код гораздо предпочтительнее статического кода/жесткого кодирования. Это экономит время и усилия, сводит к минимуму повторяемость, а также повышает удобство использования. Две приведенные выше функции подходят только для выполнения одной, конкретной операции с переданным массивом, и каждый раз необходимо писать весь цикл for!
Итак, давайте попробуем лучше придерживаться принципа обобщения и создадим функцию, которая уменьшает элементы массива в соответствии с функцией обратного вызова, переданной в качестве параметра. Это то, чем в конечном счете является .reduce(), встроенный метод в объект массива JavaScript.
Если бы мы создали .reduce() вручную, это выглядело бы примерно так:
function myReduce(array, callback, initialValue) { //will usually be 0, but can be any number //finalValue will be changed, but for now //its value is the same as initialValue let finalValue = initialValue; //iterate through the passed-in array for (const element of array) { //vitally, the callback function is //invoked with finalValue, which changes with each iteration //thus "accumulating" it finalValue = callback(finalValue, element); } return finalValue; } //A simple function used in myReduce() //that adds all elements of an array together function addValues(finalValue, element) { return finalValue + element; } //Function calls myReduce([1, 2, 3, 4], addValues, 0) //=>10 myReduce([1, 2, 3, 4], addValues, 10) //=>20 (because we started with an initialValue of 10 rather than 0)
Вот более подробное описание того, что происходит с каждой итерацией массива [1, 2, 3, 4].
1st iteration: finalValue = 0 element = array[0] = 1 finalValue = 0 + 1 = 1 2nd iteration: finalValue = 1 element = array[1] = 2 finalValue = 1 + 2 = 3 3rd iteration: finalValue = 3 element = array[2] = 3 finalValue = 3 + 3 = 6 4th iteration: finalValue = 6 element = array[3] = 4 finalValue = 6 + 4 = 10 finalValue = 10
После всего вышеизложенного механика встроенного метода .reduce() (надеюсь) станет понятнее. Как и созданный вручную myReduce.(), он принимает функцию обратного вызова и начальное значение. Но встроенный метод уже присутствует во всех объектах Array, отсюда и отсутствие параметра массива в самой функции.
//General syntax array.reduce(callback, initialValue) //Practical example [1, 2, 3, 4].reduce((initialValue, element) => initialValue + element, 0) //=>10 //Make sure that initialValue is always the first parameter!
На этом я заканчиваю объяснение метода .reduce()! Даже во время написания этого мне приходилось консультироваться и пересматривать свою курсовую работу. Я уверен, что обращусь к этому посту хотя бы раз в обозримом будущем…
Я с нетерпением жду следующего этапа буткемпа Flatiron. Двенадцать недель назад я никогда в жизни не прикасался к JavaScript, а теперь успешно создал и развернул одностраничное веб-приложение с его использованием (плюс HTML и CSS)! Проверьте это ниже, если вам интересно!