'Average with the Reduce Method in JavaScript

recently I tried to calculate Average with the Reduce Method In JavaScript​ here is may code

var arr = [129, 139, 155, 176];

var result = arr.reduce(function (start, end, index, array){
  var total =start + end;
  var array_length = array.length;
  return total/array_length;
});
console.log(result);

my result is 57.875 but it's wrong, where is my problem and how to resolve it?



Solution 1:[1]

You could add all values, who are divided by the length to get the average.

var array = [129, 139, 155, 176],
    average = array.reduce(function (avg, value, _, { length }) {
        return avg + value / length;
    }, 0);

console.log(average);

Or take the sum of all values and divide by the length of the array. The result is the same.

var array = [129, 139, 155, 176],
    average = array.reduce(function (sum, value) {
        return sum + value;
    }, 0) / array.length;

console.log(average);

Solution 2:[2]

You have repeated reduce on each item of the array. What the other answers are doing they havent reduced the array into the average result, instead they did sum and then reduced and you needed 2 steps to do that.

The good functional programmers, we wanna think as one "pure, one shot" way to transform our input data into the thing we really want. This should leave almost a little bit of code smell.

The better way to do that is you can use couple of supported arguments of the reduce function.

See the code and hope that helps with your answer. Happy coding :)

     var arr = [129, 139, 155, 176];
    
    function reducer(acc, value, index, array) {
    
      var calculatedValue = acc + value;
    
      if (index === array.length - 1) {
        return calculatedValue / array.length;
      }
    
      return calculatedValue;
    }
    
    var result = arr.reduce(reducer, 0);
    
    console.log(result);

Solution 3:[3]

What you call start in your code is in fact what is returned from the previous iteration. At each step, you add the current element of the array (you called it end) to what was returned at the previous iteration (start) and divide the sum by the length of the array. This is indeed not the average.

Here is how you can compute the average using a reducer:

const arr = [129, 139, 155, 176];

// sum all the elements of the array
const sum = arr.reduce(function (accumulator, currentValue){
  return accumulator + currentValue;
}, 0);

const average = sum / arr.length;

console.log(average);

Solution 4:[4]

Here's a solution that doesn't use array length, and can be potentially used for calculating the average for a stream of numbers:

const average = (numbersArray) =>
  numbersArray.reduce(
    (result, currentValue) => ({
      average: result.average + (currentValue - result.average) / result.count,
      count: result.count + 1,
    }),
    { average: 0, count: 1 }
  ).average;

console.log(average([1, 2, 3, 4, 5, 6]));

Solution 5:[5]

Since you specifically asked for ES6:

let arr = [129, 139, 155, 176]
let avg = arr.reduce((a,b) => a+b) / arr.length

Solution 6:[6]

Using the reduce() method you can get the average of your array. The array argument gives you the array to traverse and using that you can get the length to divide it by the sum of your array. The initialValue should be set to 0.

In addition, this works great if you need to chain methods (e.g., map() and filter()) as your array length may be different before filtering.

reduce((previousValue, currentValue, currentIndex, array) => { ... }, initialValue)

var arr = [129, 139, 155, 176];

var result = arr.reduce(
  (start, end, index, array) => start + end / array.length,
  0
);
console.log(result);

Solution 7:[7]

Just Adding an ES6+ arrow function answer here:

const arr = [22,295,176,440,37,105,10,1100,86,52] // Arr values ex.

const calcAverage = (arr) => {
    return arr.reduce((first, next) => first + next) / arr.length
}

// Or even cleaner w/o return/brackets
const calcAverage = (arr) => arr.reduce((first, next) => first + next) / arr.length

const avg = calcAverage(arr)
// Do whatever with averge

Solution 8:[8]

We can use the reduce() property in JS array.

var arr = [1, 2, 3, 4];

const average = (scores) => scores.reduce((sum, elem) => sum + elem, 0) / scores.length)
console.log(average(arr)) // 10

More details can be found here

Solution 9:[9]

Simple and elegant solution to find both moving average and average using map

const movingAverage = function (arr) {
    let avg = arr[0]
    return arr.map(current => (avg + current) / 2);
}

const average = function (arr) {
    let avg = arr[0]
    return arr.map(current => (avg + current) / 2)[arr.length-1];
}

Solution 10:[10]

You need to divide only the value by arr.length (except for the first round)

Solution 11:[11]

The following code helps see what's happening:

var arr = [129, 139, 155, 176];

var result = arr.reduce(function (start, end, index, array){
  
  var total =start + end;
  var array_length = array.length;
  var running_average = total / array_length;

  console.log(`At index ${index}`);
  console.log(`start:${start} end:${end} total:${total}`);
  console.log(`Running average: ${running_average}`);

  return running_average;
});

console.log(result);

Change your code as follows to fix the issue:

var arr = [129, 139, 155, 176];

result = arr.reduce(function(start, end, index, array){
  
  let total = start + end;
  let array_length = array.length;

  // console.log(`At index ${index}`);
  // console.log(`start:${start} end:${end} total:${total}`);
  
  if(index === array_length - 1){
    return total / array_length;
  }
  else{
    return total;
  }
});

console.log(result);

Solution 12:[12]

const arr = [129, 139, 155, 176];

const calcAverage = (scores) =>
  scores.reduce(
    (accu, ele, i, arrs) =>
      i + 1 === arrs.length ? (accu + ele) / (i + 1) : accu + ele,
    0
  );
console.log(calcAverage(arr));