Shanu T Thankachan
Shanu T Thankachan

Reputation: 1073

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?

Upvotes: 25

Views: 32024

Answers (12)

Eyal Sinay
Eyal Sinay

Reputation: 13

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

Upvotes: 0

saumilsdk
saumilsdk

Reputation: 847

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];
}

Upvotes: 0

Matt Walls
Matt Walls

Reputation: 21

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);

Upvotes: 2

kproger
kproger

Reputation: 7

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

Upvotes: -1

Maxim Mazurok
Maxim Mazurok

Reputation: 4138

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]));

Upvotes: 2

Stephen Romero
Stephen Romero

Reputation: 3032

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

Upvotes: 0

Jo.gwangil jo
Jo.gwangil jo

Reputation: 1

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));

Upvotes: -1

DarkWiiPlayer
DarkWiiPlayer

Reputation: 7064

Since you specifically asked for ES6:

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

Upvotes: 2

Hamid Ali
Hamid Ali

Reputation: 29

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);

Upvotes: -1

Baboo
Baboo

Reputation: 4278

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);

Upvotes: 3

Vlad B.
Vlad B.

Reputation: 2937

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);

Upvotes: 5

Nina Scholz
Nina Scholz

Reputation: 386746

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);

Upvotes: 35

Related Questions