How to compute the sum and average of elements in an array?

JavascriptArraysAverage

Javascript Problem Overview


I am having problems adding all the elements of an array as well as averaging them out. How would I do this and implement it with the code I currently have? The elements are supposed to be defined as I have it below.

<script type="text/javascript">
//<![CDATA[

var i;
var elmt = new Array();

elmt[0] = "0";
elmt[1] = "1";
elmt[2] = "2";
elmt[3] = "3";
elmt[4] = "4";
elmt[5] = "7";
elmt[6] = "8";
elmt[7] = "9";
elmt[8] = "10";
elmt[9] = "11";

// Problem here
for (i = 9; i < 10; i++){
  document.write("The sum of all the elements is: " + /* Problem here */ + " The average of all the elements is: " + /* Problem here */ + "<br/>");
}   

//]]>
</script>

Javascript Solutions


Solution 1 - Javascript

A solution I consider more elegant:

const sum = times.reduce((a, b) => a + b, 0);
const avg = (sum / times.length) || 0;

console.log(`The sum is: ${sum}. The average is: ${avg}.`);

Solution 2 - Javascript

var sum = 0;
for( var i = 0; i < elmt.length; i++ ){
    sum += parseInt( elmt[i], 10 ); //don't forget to add the base
}

var avg = sum/elmt.length;

document.write( "The sum of all the elements is: " + sum + " The average is: " + avg );

Just iterate through the array, since your values are strings, they have to be converted to an integer first. And average is just the sum of values divided by the number of values.

Solution 3 - Javascript

ES6

const average = arr => arr.reduce( ( p, c ) => p + c, 0 ) / arr.length;
    
const result = average( [ 4, 4, 5, 6, 6 ] ); // 5
    
console.log(result);

Solution 4 - Javascript

Calculating average (mean) using reduce and ES6:

const average = list => list.reduce((prev, curr) => prev + curr) / list.length;

const list = [0, 10, 20, 30]
average(list) // 15

Solution 5 - Javascript

Shortest one liner for Average

const avg = arr => arr.reduce((acc,v,i,a)=>(acc+v/a.length),0);

Shortest one liner for Sum

const sum = arr => arr.reduce((a,b)=>a+b);

Solution 6 - Javascript

generally average using one-liner reduce is like this

elements.reduce(function(sum, a,i,ar) { sum += a;  return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);

specifically to question asked

elements.reduce(function(sum, a,i,ar) { sum += parseFloat(a);  return i==ar.length-1?(ar.length==0?0:sum/ar.length):sum},0);

an efficient version is like

elements.reduce(function(sum, a) { return sum + a },0)/(elements.length||1);

Understand Javascript Array Reduce in 1 Minute http://www.airpair.com/javascript/javascript-array-reduce

as gotofritz pointed out seems Array.reduce skips undefined values. so here is a fix:

(function average(arr){var finalstate=arr.reduce(function(state,a) { state.sum+=a;state.count+=1; return state },{sum:0,count:0}); return finalstate.sum/finalstate.count})([2,,,6])

Solution 7 - Javascript

Let's imagine we have an array of integers like this:

var values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

The average is obtained with the following formula

A= (1/n)Σxi ( with i = 1 to n ) ... So: x1/n + x2/n + ... + xn/n

We divide the current value by the number of values and add the previous result to the returned value.

The reduce method signature is

reduce(callback[,default_previous_value])

The reduce callback function takes the following parameters:

  • p : Result of the previous calculation
  • c : Current value (from the current index)
  • i : Current array element's index value
  • a : The current reduced Array

The second reduce's parameter is the default value ... (Used in case the array is empty ).

So the average reduce method will be:

var avg = values.reduce(function(p,c,i,a){return p + (c/a.length)},0);

If you prefer you can create a separate function

function average(p,c,i,a){return p + (c/a.length)};
function sum(p,c){return p + c)};

And then simply refer to the callback method signature

var avg = values.reduce(average,0);
var sum= values.reduce(sum,0);

Or Augment the Array prototype directly..

Array.prototype.sum = Array.prototype.sum || function (){
  return this.reduce(function(p,c){return p+c},0);
};

It's possible to divide the value each time the reduce method is called..

Array.prototype.avg = Array.prototype.avg || function () {
  return this.reduce(function(p,c,i,a){return p+(c/a.length)},0);
};

Or even better , using the previously defined Array.protoype.sum()

method, optimize the process my calling the division only once :)

Array.prototype.avg = Array.prototype.avg || function () {
  return this.sum()/this.length; 
};

Then on any Array object of the scope:

[2, 6].avg();// -> 4
[2, 6].sum();// -> 8

NB: an empty array with return a NaN wish is more correct than 0 in my point of view and can be useful in specific use cases.

Solution 8 - Javascript

You can also use lodash, _.sum(array) and _.mean(array) in Math part (also have other convenient stuff).

_.sum([4, 2, 8, 6]);
// => 20
_.mean([4, 2, 8, 6]);
// => 5

Solution 9 - Javascript

Not the fastest, but the shortest and in one line is using map() & reduce():

var average = [7,14,21].map(function(x,i,arr){return x/arr.length}).reduce(function(a,b){return a + b})

Solution 10 - Javascript

I use these methods in my personal library:

Array.prototype.sum = Array.prototype.sum || function() {
  return this.reduce(function(sum, a) { return sum + Number(a) }, 0);
}

Array.prototype.average = Array.prototype.average || function() {
  return this.sum() / (this.length || 1);
}

EDIT: To use them, simply ask the array for its sum or average, like:

[1,2,3].sum() // = 6
[1,2,3].average() // = 2

Solution 11 - Javascript

In ES6-ready browsers this polyfill may be helpful.

Math.sum = (...a) => Array.prototype.reduce.call(a,(a,b) => a+b)

Math.avg = (...a) => this.sum(...a)/a.length;

You can share same call method between Math.sum,Math.avg and Math.max,such as

var maxOne = Math.max(1,2,3,4) // 4;

you can use Math.sum as

var sumNum = Math.sum(1,2,3,4) // 10

or if you have an array to sum up,you can use

var sumNum = Math.sum.apply(null,[1,2,3,4]) // 10

just like

var maxOne = Math.max.apply(null,[1,2,3,4]) // 4

Solution 12 - Javascript

One sneaky way you could do it although it does require the use of (the much hated) eval().

var sum = eval(elmt.join('+')), avg = sum / elmt.length;
document.write("The sum of all the elements is: " + sum + " The average of all the elements is: " + avg + "<br/>");

Just thought I'd post this as one of those 'outside the box' options. You never know, the slyness might grant you (or taketh away) a point.

Solution 13 - Javascript

Here is a quick addition to the “Math” object in javascript to add a “average” command to it!!

Math.average = function(input) {
  this.output = 0;
  for (this.i = 0; this.i < input.length; this.i++) {
    this.output+=Number(input[this.i]);
  }
  return this.output/input.length;
}

Then i have this addition to the “Math” object for getting the sum!

Math.sum = function(input) {
  this.output = 0;
  for (this.i = 0; this.i < input.length; this.i++) {
    this.output+=Number(input[this.i]);
  }
  return this.output;
}

So then all you do is

alert(Math.sum([5,5,5])); //alerts “15”
alert(Math.average([10,0,5])); //alerts “5”

And where i put the placeholder array just pass in your variable (The input if they are numbers can be a string because of it parsing to a number!)

Solution 14 - Javascript

set your for loop counter to 0.... you're getting element 9 and then you're done as you have it now. The other answers are basic math. Use a variable to store your sum (need to cast the strings to ints), and divide by your array length.

Solution 15 - Javascript

Start by defining all of the variables we plan on using. You'll note that for the numbers array, I'm using the literal notation of [] as opposed to the constructor method array(). Additionally, I'm using a shorter method to set multiple variables to 0.

var numbers = [], count = sum = avg = 0;

Next I'm populating my empty numbers array with the values 0 through 11. This is to get me to your original starting point. Note how I'm pushing onto the array count++. This pushing the current value of count, and then increments it for the next time around.

while ( count < 12 )
    numbers.push( count++ );

Lastly, I'm performing a function "for each" of the numbers in the numbers array. This function will handle one number at a time, which I'm identifying as "n" within the function body.

numbers.forEach(function(n){
  sum += n; 
  avg = sum / numbers.length;
});

In the end, we can output both the sum value, and the avg value to our console in order to see the result:

// Sum: 66, Avg: 5.5
console.log( 'Sum: ' + sum + ', Avg: ' + avg );

See it in action online at http://jsbin.com/unukoj/3/edit

Solution 16 - Javascript

I am just building on Abdennour TOUMI's answer. here are the reasons why:

1.) I agree with Brad, I do not think it is a good idea to extend object that we did not create.

2.) array.length is exactly reliable in javascript, I prefer Array.reduce beacuse a=[1,3];a[1000]=5; , now a.length would return 1001.

function getAverage(arry){
    // check if array
    if(!(Object.prototype.toString.call(arry) === '[object Array]')){
        return 0;
    }
    var sum = 0, count = 0; 
    sum = arry.reduce(function(previousValue, currentValue, index, array) {
        if(isFinite(currentValue)){
            count++;
            return previousValue+ parseFloat(currentValue);
        }
        return previousValue;
    }, sum);
    return count ? sum / count : 0; 
};

Solution 17 - Javascript

Array.prototype.avg=function(fn){
    fn =fn || function(e,i){return e};
    return (this.map(fn).reduce(function(a,b){return parseFloat(a)+parseFloat(b)},0) / this.length ) ; 
};

Then :

[ 1 , 2 , 3].avg() ;  //-> OUT : 2

[{age:25},{age:26},{age:27}].avg(function(e){return e.age}); // OUT : 26

Solution 18 - Javascript

On evergreen browsers you can use arrow functions avg = [1,2,3].reduce((a,b) => (a+b);

Running it 100,000 times, the time difference between the for loop approach and reduce is negligible.

s=Date.now();for(i=0;i<100000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("100k reduce took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<100000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("100k for loop took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<1000000;i++){n=[1,2,3]; nl=n.length; a=0; for(j=nl-1;j>0;j--){a=a+n[j];} a/nl };
console.log("1M for loop took " + (Date.now()-s) + "ms.");

s=Date.now();for(i=0;i<1000000;i++){ n=[1,2,3]; a=n.reduce((a,b) => (a+b)) / n.length };
console.log("1M reduce took " + (Date.now()-s) + "ms.");

/* 
 * RESULT on Chrome 51
 * 100k reduce took 26ms.
 * 100k for loop took 35ms.
 * 10M for loop took 126ms.
 * 10M reduce took 209ms.
 */

Solution 19 - Javascript

If you are in need of the average and can skip the requirement of calculating the sum, you can compute the average with a single call of reduce:

// Assumes an array with only values that can be parsed to a Float
var reducer = function(cumulativeAverage, currentValue, currentIndex) {
  // 1. multiply average by currentIndex to find cumulative sum of previous elements
  // 2. add currentValue to get cumulative sum, including current element
  // 3. divide by total number of elements, including current element (zero-based index + 1)
  return (cumulativeAverage * currentIndex + parseFloat(currentValue))/(currentIndex + 1)
}
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].reduce(reducer, 0)); // => 5.5
console.log([].reduce(reducer, 0)); // => 0
console.log([0].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0
console.log([,,,].reduce(reducer, 0)); // => 0
console.log([].reduce(reducer, 0)); // => 0

Solution 20 - Javascript

If anyone ever needs it - Here is a recursive average.

In the context of the original question, you may want to use the recursive average if you allowed the user to insert additional values and, without incurring the cost of visiting each element again, wanted to "update" the existing average.

/**
 * Computes the recursive average of an indefinite set
 * @param {Iterable<number>} set iterable sequence to average
 * @param {number} initAvg initial average value
 * @param {number} initCount initial average count
 */
function average(set, initAvg, initCount) {
  if (!set || !set[Symbol.iterator])
    throw Error("must pass an iterable sequence");

  let avg = initAvg || 0;
  let avgCnt = initCount || 0;
  for (let x of set) {
    avgCnt += 1;
    avg = avg * ((avgCnt - 1) / avgCnt) + x / avgCnt;
  }
  return avg; // or {avg: avg, count: avgCnt};
}

average([2, 4, 6]);    //returns 4
average([4, 6], 2, 1); //returns 4
average([6], 3, 2);    //returns 4
average({
  *[Symbol.iterator]() {
    yield 2; yield 4; yield 6;
  }
});                    //returns 4

How:

this works by maintaining the current average and element count. When a new value is to be included you increment count by 1, scale the existing average by (count-1) / count, and add newValue / count to the average.

Benefits:

  • you don't sum all the elements, which may result in large number that cannot be stored in a 64-bit float.
  • you can "update" an existing average if additional values become available.
  • you can perform a rolling average without knowing the sequence length.

Downsides:

  • incurs lots more divisions
  • not infinite - limited to Number.MAX_SAFE_INTEGER items unless you employ BigNumber

Solution 21 - Javascript

Having read the other choices, I will try to make a simpler version for the future viewers, elaborating on the existing code and not creating a more elegant one. First of all, you declared the numbers as strings. Apart from the .parseInt we can also do:

const numberConverter = elmt.map(Number);

So what map does is that it "returns a copy of the original array". But I convert its values to numbers. Then we can use the reduce method (It can also be simpler, but I am writing easy to read versions and I also have 2 average methods) What the reduce method does is it has an accumulator that gets bigger and bigger if you add values to it, as it iterates through the array and adds (in this case) the currentValue to it.:

var i;
const elmt = new Array();
elmt[0] = '0';
elmt[1] = '1';
elmt[2] = '2';
elmt[3] = '3';
elmt[4] = '4';
elmt[5] = '7';
elmt[6] = '8';
elmt[7] = '9';
elmt[8] = '10';
elmt[9] = '11';

console.log(elmt);

const numberConverter = elmt.map(Number);

const sum = numberConverter.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0);

const average = numberConverter.reduce(
  (accumulator, currentvalue, index, numArray) => {
    return accumulator + currentvalue / numArray.length;
  },
  0
);

const average2 =
  numberConverter.reduce(
    (accumulator, currentValue) => accumulator + currentValue,
    0
  ) / numberConverter.length;

for (i = 9; i < 10; i++) {
  console.log(
    `The sum of all the elements is: ${sum}. <br> The average of all the elements is: ${average2}`
  );}

Solution 22 - Javascript

I found Mansilla's answer to work fine with the extension of making sure that I am doing summation of floats and not concatonation of strings using parseFloat():

let sum = ourarray.reduce((a, b) => parseFloat(a) + parseFloat(b), 0);
let avg = (sum / ourarray.length) || 0;

console.log(sum); // print out sum
console.log(avg); // print out avg

Solution 23 - Javascript

Just for kicks:

var elmt = [0, 1, 2,3, 4, 7, 8, 9, 10, 11], l = elmt.length, i = -1, sum = 0;
for (; ++i < l; sum += elmt[i])
    ;
document.body.appendChild(document.createTextNode('The sum of all the elements is: ' + sum + ' The average of all the elements is: ' + (sum / l)));

Solution 24 - Javascript

I think we can do like

var k=elmt.reduce(function(a,b){return parseFloat(a+parseFloat(b));})
var avg=k/elmt.length; 
console.log(avg);

I am using parseFloat twice because when

  1. you add (a)9+b("1") number then result will be "91" but we want addition. so i used parseFloat

2)When addition of (a)9+parseFloat("1") happen though result will be "10" but it will be in string which we don't want so again i used parseFloat.

I hope i am clear. Suggestions are welcome

Solution 25 - Javascript

Here is my rookie way of simply finding the avg. Hope this helps somebody.

function numAvg(num){
    var total = 0;
    for(var i = 0;i < num.length; i++) { 
        total+=num[i];
    }
    return total/num.length;
}

Solution 26 - Javascript

here's your one liner:

var average = arr.reduce((sum,item,index,arr)=>index !== arr.length-1?sum+item:sum+item/arr.length,0)

Solution 27 - Javascript

I think this may be a direct solution to calculate the average with a for loop and function.

var elmts = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];

function average(arr) {
	var total = 0;
	for (var i = 0; i < arr.length; i++) {
	    total += arr[i];
	}
        console.log(Math.round(total/arr.length));
}

average(elmts);

Solution 28 - Javascript

There seem to be an endless number of solutions for this but I found this to be concise and elegant.

const numbers = [1,2,3,4];
const count = numbers.length;
const reducer = (adder, value) => (adder + value);
const average = numbers.map(x => x/count).reduce(reducer);
console.log(average); // 2.5

Or more consisely:

const numbers = [1,2,3,4];
const average = numbers.map(x => x/numbers.length).reduce((adder, value) => (adder + value));
console.log(average); // 2.5

Depending on your browser you may need to do explicit function calls because arrow functions are not supported:

const r = function (adder, value) {
        return adder + value;
};
const m = function (x) {
        return x/count;
};
const average = numbers.map(m).reduce(r);
console.log(average); // 2.5

Or:

const average1 = numbers
    .map(function (x) {
        return x/count;
     })
    .reduce(function (adder, value) {
        return adder + value;
});
console.log(average1);

Solution 29 - Javascript

Average of HTML content itens

With jQuery or Javascript's querySelector you have direct acess to formated data... Example:

<p>Elements for an average: <span class="m">2</span>, <span class="m">4</span>,
   <span class="m">2</span>, <span class="m">3</span>.
</p>

So, with jQuery you have

var A = $('.m')
  .map(function(idx) { return  parseInt($(this).html()) })
  .get();
var AVG = A.reduce(function(a,b){return a+b}) / A5.length;

See other more 4 ways (!) to access itens and average it: http://jsfiddle.net/4fLWB/

Solution 30 - Javascript

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

function avg(arr){
  var sum = 0;
  for (var i = 0; i < arr.length; i++) {
    sum += parseFloat(arr[i])
  }
  return sum / i;
}

avg(arr) ======>>>> 3

This works with strings as numbers or numbers in the array.

Solution 31 - Javascript

    var scores =[90, 98, 89, 100, 100, 86, 94];
        var sum = 0;
        var avg = 0;
        for(var i = 0; i < scores.length;i++){
  //Taking sum of all the arraylist
            sum = sum + scores[i];   
                }
  //Taking average     
             avg = sum/scores.length;        
  //this is the function to round a decimal no    
             var round = avg.toFixed();
             console.log(round);

Solution 32 - Javascript

I would recommend D3 in this case. It is the most readable (and provides 2 different kinds of averages)

let d3 = require('d3');
let array = [1,2,3,4];
let sum = d3.sum(array); //10
let mean = d3.mean(array); //2.5
let median = d3.median(array); 

Solution 33 - Javascript

I had exactly 10 elements (like in the example) so I did:

( elmt[0] + elmt[1] + elmt[2] + elmt[3] + elmt[4] +
  elmt[5] + elmt[6] + elmt[7] + elmt[8] + elmt[9] ) / 10

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionjonathan millerView Question on Stackoverflow
Solution 1 - JavascriptSergi MansillaView Answer on Stackoverflow
Solution 2 - JavascriptMarcus RecckView Answer on Stackoverflow
Solution 3 - JavascriptAbdennour TOUMIView Answer on Stackoverflow
Solution 4 - JavascriptTomasz MularczykView Answer on Stackoverflow
Solution 5 - JavascriptchickensView Answer on Stackoverflow
Solution 6 - JavascriptShimon DoodkinView Answer on Stackoverflow
Solution 7 - JavascriptLudovic FrérotView Answer on Stackoverflow
Solution 8 - JavascriptGeng JiawenView Answer on Stackoverflow
Solution 9 - JavascriptJohann EchavarriaView Answer on Stackoverflow
Solution 10 - JavascriptKeithView Answer on Stackoverflow
Solution 11 - JavascriptOboo ChengView Answer on Stackoverflow
Solution 12 - JavascriptPhil CooperView Answer on Stackoverflow
Solution 13 - JavascriptJacob MorrisView Answer on Stackoverflow
Solution 14 - JavascriptVolvoxView Answer on Stackoverflow
Solution 15 - JavascriptSampsonView Answer on Stackoverflow
Solution 16 - JavascriptmidoView Answer on Stackoverflow
Solution 17 - JavascriptAbdennour TOUMIView Answer on Stackoverflow
Solution 18 - JavascriptRay FossView Answer on Stackoverflow
Solution 19 - JavascriptsealocalView Answer on Stackoverflow
Solution 20 - JavascriptMeirion HughesView Answer on Stackoverflow
Solution 21 - Javascriptuser12517877View Answer on Stackoverflow
Solution 22 - JavascriptzabopView Answer on Stackoverflow
Solution 23 - Javascriptuser1720624View Answer on Stackoverflow
Solution 24 - JavascriptRoli AgrawalView Answer on Stackoverflow
Solution 25 - JavascriptJeremiahView Answer on Stackoverflow
Solution 26 - JavascriptAlex C.View Answer on Stackoverflow
Solution 27 - JavascriptredcoderView Answer on Stackoverflow
Solution 28 - JavascriptCharles OwenView Answer on Stackoverflow
Solution 29 - JavascriptPeter KraussView Answer on Stackoverflow
Solution 30 - Javascriptdan chowView Answer on Stackoverflow
Solution 31 - JavascriptHannan SaleemView Answer on Stackoverflow
Solution 32 - JavascriptCode WhispererView Answer on Stackoverflow
Solution 33 - Javascriptuser40521View Answer on Stackoverflow