CJ Johnson
CJ Johnson

Reputation: 1101

Javascript Averages

I am trying to learn Javascript. I've built the following code to find the average from an array of numbers. It works except the last returned value is always NaN. I cannot figure out why. If I move this piece outside of the block it seems to forget altogether what the variable sum is supposed to be equal to. Is there some kind of global-variable type equivalent I'm supposed to be using for JS?

var average = function(myarray) {
    sum = 0;
    for (counter = 0; counter <= myarray.length; counter++) {
        sum = sum + myarray[counter];
        average = sum / myarray.length;
        console.log(average);
    };
}

average([1, 2, 3])

Upvotes: 1

Views: 142

Answers (5)

cmd
cmd

Reputation: 11841

You can calculate the average of an array of numbers as follows:

var avg = c => c.reduce((a,b) => a +b) / c.length;
avg([1,2,3])

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239443

  1. Don't use variables without declaring them with var keyword, otherwise they will become global properties.

  2. The JavaScript Arrays are zero index based arrays. So, if the size of the array is 3, then the first element will be accessed with 0 and the last with 2. JavaScript is very forgiving, so when you access an element at an invalid index in the array, it will simply return undefined.

  3. In the iteration, you are replacing the current function object with the average value. So, subsequent calls to average will fail, since average is not a function object any more.

  4. It is a good practice to have a function return the computed value, instead of printing the value, so that it will not violate the Single Responsibility Principle.

In your case,

for (counter = 0; counter <= myarray.length; counter++) {

The counter runs till the last index of the array + 1. Since it returns undefined in the last iteration, JavaScript returns NaN in the arithmetic operation.

console.log(1 + undefined);
# NaN

So, you need to change the code, like this

function Average(myarray) {
    var sum = 0, counter;
    for (counter = 0; counter < myarray.length; counter++) {
        sum = sum + myarray[counter];
    }
    return sum / myarray.length;
}

If you are interested, you can compute the sum with Array.prototype.forEach, like this

function Average(myarray) {
    var sum = 0;
    myarray.forEach(function(currentNumber) {
        sum += currentNumber;
    });
    return sum / myarray.length;
}

Even better, you can calculate the sum with Array.prototype.reduce, like this

function Average(myarray) {
    return myarray.reduce(function(sum, currentNumber) {
        return sum + currentNumber;
    }, 0) / myarray.length;
}

Upvotes: 0

Miguel
Miguel

Reputation: 20633

Change

counter <= myarray.length

to

counter < myarray.length

because indexes start at 0.

Full example:

var average = function(myarray) {
  var sum = 0;
  for (var counter = 0; counter < myarray.length; counter++) {
    sum += myarray[counter];
   }

   return sum / myarray.length;
}

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

JSBin Demo: http://jsbin.com/siyugi/1/edit

Upvotes: 1

EvilZebra
EvilZebra

Reputation: 1072

Since you are just learning you should know it is good practice to not use .length in a for loop like that. It causes the code to have to check the length of your array on each loop. And remember that .length is returning the number of elements in the array; but array index starts at 0.

for(var counter = 0, length = myarray.length; counter < length; counter++){
}

Would be the proper way to do it.

Upvotes: 0

Valentin Waeselynck
Valentin Waeselynck

Reputation: 6051

myarray[myarray.length] is undefined, which intoxicates your computation with NaN(Not A Number).

Just change it to

for(counter = 0; counter < myarray.length; counter ++) {
// ...
}

Upvotes: 1

Related Questions