Imagine having an array of integers:
const values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
To calculate the average, we use this formula:
A= (1/n)Σxi ( where i = 1 to n ) ... In other words: x1/n + x2/n + ... + xn/n
We divide the current value by the total number of values and add it to the sum of previous results.
The signature for the reduce method is as follows:
reduce(callback[,default_previous_value])
The callback function in reduce accepts these parameters:
- p : Result of the previous calculation
- c : Current value (from the current index)
- i : Index value of the current array element
- a : The current reduced Array
The default value for the second parameter in reduce is used when the array is empty.
Thus, the average using reduce method can be calculated like this:
const avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);
You may also create separate functions:
function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};
And reference them in reduce method like so:
const avg = values.reduce(average,0);
const sum = values.reduce(sum,0);
Alternatively, you can extend the Array prototype directly:
Array.prototype.sum = Array.prototype.sum || function (){
return this.reduce(function(p,c){return p+c},0);
};
Each time reduce method is called, dividing the value is possible:
Array.prototype.avg = Array.prototype.avg || function () {
return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};
Or better yet, utilizing the previously defined Array.protoype.sum()
to optimize the process by performing division only once:
Array.prototype.avg = Array.prototype.avg || function () {
return this.sum()/this.length;
};
Then on any Array object within the scope:
[2, 6].avg();// -> 4
[2, 6].sum();// -> 8
Note: An empty array will yield NaN which can be more accurate than 0 in specific cases.