48

I have an array containing some values and I want to get their sum. Here is the example:

var somearray = ["20","40","80","400"];

I want to sum these values using jQuery. In this example the result would be 540.

Paul Bellora
  • 53,024
  • 17
  • 128
  • 180
Aman Virk
  • 3,739
  • 8
  • 38
  • 51

9 Answers9

75

To also handle floating point numbers:

  • (Older) JavaScript:

    var arr = ["20.0","40.1","80.2","400.3"],
        n   = arr.length,
        sum = 0;
    while(n--)
       sum += parseFloat(arr[n]) || 0;
    
  • ECMA 5.1/6:

    var arr = ["20.0","40.1","80.2","400.3"],
        sum = 0;
    arr.forEach(function(num){sum+=parseFloat(num) || 0;});
    
  • ES6:

    var sum = ["20.0","40.1","80.2","400.3"].reduce((pv,cv)=>{
       return pv + (parseFloat(cv)||0);
    },0);
    

    The reduce() is available in older ECMAScript versions, the arrow function is what makes this ES6-specific.

    I'm passing in 0 as the first pv value, so I don't need parseFloat around it — it'll always hold the previous sum, which will always be numeric. Because the current value, cv, can be non-numeric (NaN), we use ||0 on it to skip that value in the array. This is terrific if you want to break up a sentence and get the sum of the numbers in it. Here's a more detailed example:

    let num_of_fruits = `
       This is a sentence where 1.25 values are oranges 
       and 2.5 values are apples. How many fruits are 
       there?
    `.split(/\s/g).reduce((p,c)=>p+(parseFloat(c)||0), 0); 
    
    // num_of_fruits == 3.75
    

  • jQuery:

    var arr = ["20.0","40.1","80.2","400.3"],
        sum = 0;
    $.each(arr,function(){sum+=parseFloat(this) || 0;});
    

What the above gets you:

  • ability to input any kind of value into the array; number or numeric string(123 or "123"), floating point string or number ("123.4" or 123.4), or even text (abc)
  • only adds the valid numbers and/or numeric strings, neglecting any bare text (eg [1,'a','2'] sums to 3)
vol7ron
  • 38,313
  • 20
  • 110
  • 168
59

You don't need jQuery. You can do this using a for loop:

var total = 0;
for (var i = 0; i < someArray.length; i++) {
    total += someArray[i] << 0;
}

Related:

Community
  • 1
  • 1
Mark Byers
  • 767,688
  • 176
  • 1,542
  • 1,434
30

You can use reduce which works in all browser except IE8 and lower.

["20","40","80","400"].reduce(function(a, b) {
    return parseInt(a, 10) + parseInt(b, 10);
})
Codler
  • 10,414
  • 6
  • 51
  • 64
  • You don't need to `parseInt(a)` because `a` is the previous `reduce` return, it's already a number. Well, except for the first call, but then you could add `0` as a parameter to reduce and it'd be okay. – gberger Jul 02 '14 at 21:06
  • This is the closest to what I wanted. So.. does jQuery have a browser-independent reduce (like underscore?)? http://bugs.jquery.com/ticket/1886 - god this is amazingly stupid – Lodewijk Jul 26 '14 at 11:09
27

Another method, if eval is safe & fast :

eval(["10","20","30","40","50"].join("+"))
Codler
  • 10,414
  • 6
  • 51
  • 64
Praveen Vijayan
  • 6,133
  • 2
  • 28
  • 27
  • 14
    This is an amazingly weird solution. I don't know about it's performance, it's that weird. As a side note: please, never use eval if you can. – Lodewijk Jul 26 '14 at 11:04
  • In general it is really not recommend to use eval because one can seldom guarantee that it is safe and (my guess) it also won't be (much) faster than reduce. – Trilarion Jan 07 '16 at 20:56
  • Why "never use eval"? I had to use it at my last contract because we were storing functions in JSON in a database (I didn't design it) as strings. Sometimes it's the appropriate solution. – Dexygen Jan 22 '16 at 21:22
12

If you want it to be a jquery method, you can do it like this :

$.sum = function(arr) {
    var r = 0;
    $.each(arr, function(i, v) {
        r += +v;
    });
    return r;
}

and call it like this :

var sum = $.sum(["20", "40", "80", "400"]);
gion_13
  • 40,487
  • 10
  • 96
  • 107
8
var total = 0;
$.each(someArray,function() {
    total += parseInt(this, 10);
});

Codler
  • 10,414
  • 6
  • 51
  • 64
Sudhir Bastakoti
  • 97,363
  • 15
  • 155
  • 158
6

You can do it in this way.

var somearray = ["20","40","80","400"];

somearray = somearray.map(Number);

var total = somearray.reduce(function(a,b){  return a+b },0)

console.log(total);
RIYAJ KHAN
  • 14,597
  • 5
  • 30
  • 52
5

In http://bugs.jquery.com/ticket/1886 it becomes obvious that the jQuery devs have serious mental issues reg. functional programming inspired additions. Somehow it's good to have some fundamental things (like map) but not others (like reduce), unless it reduces jQuery's overall filesize. Go figure.

Helpfully, someone placed code to use the normal reduce function for jQuery arrays:

$.fn.reduce = [].reduce;

Now we can use a simple reduce function to create a summation:

//where X is a jQuery array
X.reduce(function(a,b){ return a + b; });
// (change "a" into parseFloat("a") if the first a is a string)

Lastly, as some older browsers hadn't yet implemented reduce, a polyfill can be taken from MDN (it's big but I guess it has the exact same behavior, which is desirable):

if ( 'function' !== typeof Array.prototype.reduce ) {
    Array.prototype.reduce = function( callback /*, initialValue*/ ) {
        'use strict';
        if ( null === this || 'undefined' === typeof this ) {
          throw new TypeError(
             'Array.prototype.reduce called on null or undefined' );
        }
        if ( 'function' !== typeof callback ) {
          throw new TypeError( callback + ' is not a function' );
        }
        var t = Object( this ), len = t.length >>> 0, k = 0, value;
        if ( arguments.length >= 2 ) {
          value = arguments[1];
        } else {
          while ( k < len && ! k in t ) k++; 
          if ( k >= len )
            throw new TypeError('Reduce of empty array with no initial value');
          value = t[ k++ ];
        }
        for ( ; k < len ; k++ ) {
          if ( k in t ) {
             value = callback( value, t[k], k, t );
          }
        }
        return value;
      };
    }
Lodewijk
  • 3,341
  • 2
  • 17
  • 14
1
    var arr = ["20.0","40.1","80.2","400.3"],
    sum = 0;
$.each(arr,function(){sum+=parseFloat(this) || 0; });

Worked perfectly for what i needed. Thanks vol7ron

Annunaki
  • 11
  • 4