user10462904
user10462904

Reputation:

im getting a "NaN" when i use the reduce method on such array of objecs

so i want to get the average "Rating" of an array full of student objects (name , age , Rating ....etc) so i used the reduce method to calculate that... which is like :

var std = [
  {
      name : 'david',
      Rating:'8',
      age:'10'  
  },
  {
      name : 'tomas',
      Rating:'5',
      age:'10'
  },
  {
      name : 'raul',
      Rating:'2',
      age:'10'
  }
]
var averageRating = std.reduce(
  (acc,val) => {
      Number(acc.Rating) + Number(val.Rating)) / std.length
  }
)
console.log(averageRating); // output NaN

Upvotes: 1

Views: 142

Answers (2)

towc
towc

Reputation: 2034

Short answer

Add 0 as an argument to .reduce, to provide an initial value for acc

Reason

You didn't provide an initial value, as a second parameter to .reduce

If no initial value is provided, then .reduce will use the first item of the array, and start running the functions from the second one.

Right now, the first iteration is running object/number, which is NaN, then the acc will be NaN, so the next iteration will do NaN/number, which is still NaN and so forth, until the last value will actually be NaN

For more info on how to use .reduce, look at the mdn page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

General problem example

const array = ["hi", "there", "what's", "up"];
const charCount = array.reduce((acc, val) => acc + val.length);

Here, charCount will actually be "hi562"

What happened is that the first acc was set to "hi", to which was added "there".length and so on.

To fix it, you can do this:

const array = ["hi", "there", "what's", "up"];
const charCount = array.reduce((acc, val) => acc + val.length, 0);

Here, charCount is correctly 15, as initially, acc=0, to which a number is added, and so on

Additional notes

This is actually not your only problem, but it's easy for you to figure out the rest of them from here. Mainly, you don't want acc.Rating, but simply acc

Upvotes: 2

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28475

Problem with your code was that if you do not supply initial value, then acc takes the first value and val takes the second value.

In this case, for first iteration, first 2 items from array are taken and value is calculated which happens to be a number. For second iteration, acc is no longer an object and hence, the calculations will fail.

Try following

  • Give initial value 0 to reduce function
  • Update reduce function to only calculate sum and then divide the result by length of array

var std = [{name: 'david',Rating: '8',age: '10'}, {name: 'tomas',Rating: '5',age: '10'}, {name: 'raul',Rating: '2',age: '10'}];

let avg = std.reduce((a,c) => a + Number(c.Rating), 0)/std.length;
console.log(avg);

Upvotes: 3

Related Questions