How to compute the sum and average of elements in

2020-01-23 04:30发布

问题:

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.

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>

回答1:

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.



回答2:

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}.`);


回答3:

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



回答4:

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


回答5:

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


回答6:

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.



回答7:

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


回答8:

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


回答9:

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


回答10:

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


回答11:

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.



回答12:

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



回答13:

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.



回答14:

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



回答15:

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


回答16:

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


回答17:

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.
 */



回答18:

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


回答19:

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



回答20:

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


回答21:

here's your one liner:

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


回答22:

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


回答23:

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


回答24:

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


回答25:

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


回答26:

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/



回答27:

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.



回答28:

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


回答29:

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


回答30:

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