Array.prototype.reduce
Understanding Array.prototype.reduce() method and how it is possibly implemented.
The Array.prototype.reduce() method reduces an array to a single value.
It accepts two parameters: a callback function(reducer), and an initial value.
The reducer function returns a value while cycling through each array element.
The initial value is optional. If given, it becomes the value of the accumulator in the first iteration.
The reducer callback accepts four parameters:
- Accumulator: it is the value returned from the previous reducer call. In the first iteration, the value of the accumulator is the initial value. If the initial value is not given, the value of the accumulator is the first element in the array (array[0]). The final value of the accumulator becomes the return value of the Array.prototype.reduce().
- Current value: the value of the current element. In the first iteration, if the initial value is specified, the current value is the first element in the array (array[0]), else, it is the second element in the array (array[1]).
- Current index: the index of the current value.
- Array: the array which Array.prototype.reduce() is called on.
let nums = [1,4,3,2];
nums.reduce((acc, currentVal, currentInd, arr) => {
return acc + currentVal;
}, 2);
// returns 12
From the code snippet, the reduce() method is called on the nums array. Array.prototype.reduce() takes a reducer function and an initial value of 2.
In the first iteration, the accumulator is equal to the initial value (2) and the current value is array[0]. The reducer then returns 2 + 1 which is 3. This return value is assigned to the accumulator.
In the second iteration, the accumulator is equal to 3 and the current value is array[1]. The reducer then returns 3 + 4 which is 7. This value is assigned to the accumulator.
In the third iteration, the accumulator is equal to 7 and the current value is array[2]. The reducer returns 7 + 3 which is 10. The accumulator is assigned this returned value.
In the fourth iteration (last), the accumulator is equal to 10 and the current value is array[3]. The reducer returns 10 + 2 which is 12. The accumulator is assigned this value.
The accumulator’s value (12) becomes the return value of the Array.prototype.reduce() method.
There are three special cases:
- If the array is empty and the initial value is not given, a TypeError is thrown.
- If the array has only one element and the initial value is not given, the element in the array is returned without calling the reducer.
- If the array is empty and the initial value is given, the initial value is returned without calling the reducer.
Let us see how the Array.prototype.reduce() method can be possibly implemented by creating our own method (gReduce) in the Array.prototype object.
Array.prototype.gReduce = function(callback, initialVal){
let context = this;
if(context.length === 0 && initialVal === undefined){
throw new TypeError('Reduce of empty array with no initial value');
}
if(context.length === 1 && initialVal === undefined){
return context[0];
}
for(let i = 0; i < context.length; i++){
if(initialVal === undefined){
initialVal = callback(context[i], context[i+1], i+1, context);
i++;
continue;
}else{
initialVal = callback(initialVal, context[i], i, context);
}
}
return initialVal;
}
[1,2,3,4].gReduce((acc, currentVal, currentIndex, arr) => {
return acc + currentVal;
}, 2)
// returns 12;
Looking at the implementation, the 3 special cases were handled first.
If the array is empty and the initial value is not given, a TypeError is thrown.
if(context.length === 0 && initialVal === undefined){
throw new TypeError('Reduce of empty array with no initial value');
}
If the array has only one element and the initial value is not given, the element in the array is returned without calling the reducer.
if(context.length === 1 && initialVal === undefined){
return context[0];
}
If the array is empty and the initial value is given, the initial value is returned without calling the reducer. The condition in the for loop handles that because the array’s length is not greater than zero.
for(let i = 0; i < context.length; i++)
Conclusion
The Array.prototype.reduce() method is a powerful method to use but if not clearly understood, it should be avoided. This article is written to clearly explain how it works.
The Array.prototype.reduce() method is called on an array and returns a single value. This can be used for various use cases:
- Sum of values
- Grouping an object
- Cleaning an array
- etc.
If you like this post, kindly clap, comment and follow.
Thanks for reading.