49

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
  • 54,340
  • 18
  • 130
  • 181
Aman Virk
  • 3,909
  • 8
  • 40
  • 51

9 Answers9

79

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
  • 40,809
  • 21
  • 119
  • 172
60

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
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 8
    You should not use `for(x in someArray)` with arrays because it enumerates enumerable properties of the array, not just the array elements. You should use `for (var i = 0; i < someArray.length; i++)` on arrays. – jfriend00 Dec 18 '11 at 06:39
  • 2
    Minor: cache the length field so it doesn't have to check on each iteration; `for (var i = 0, len = someArray.length; i < len; i++)` – lrusli Dec 18 '11 at 07:52
  • 5
    @MarkByers what does `<<` stand for? – BeNdErR Jul 02 '14 at 15:43
  • @BeNdErR Left shift, it's binary operation. In his example he's shifing 0 to the left. – eestein Oct 22 '14 at 12:31
  • is there any function like `PHP`'s `array_sum()` in Javascript? – Oki Erie Rinaldi Nov 29 '14 at 01:32
  • @OkiErieRinaldi Why would there need (or should there) be? One cane be trivially written one using any one of the proposed solutions. (This operation is even easier if using a fold higher-order function which is available in several flavors.) – user2864740 May 17 '15 at 06:57
  • @MarkByers I am not clear why there is need of left shift?Please help me – RIYAJ KHAN Jun 07 '16 at 08:56
  • 1
    @BeNdErR and @RIYAJKHAN, the left shift `<<` is used to convert the string elements to numerics so they can be added and not concatenated. – haferje Nov 11 '16 at 20:45
  • It works for me :) – Harshad Patil Aug 23 '17 at 14:57
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,951
  • 6
  • 52
  • 65
  • 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,951
  • 6
  • 52
  • 65
Praveen Vijayan
  • 6,521
  • 2
  • 29
  • 28
  • 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. – NoDataDumpNoContribution 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
  • 41,171
  • 10
  • 96
  • 108
8
var total = 0;
$.each(someArray,function() {
    total += parseInt(this, 10);
});

Codler
  • 10,951
  • 6
  • 52
  • 65
Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
7

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,741
  • 2
  • 18
  • 15
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
  • 15,032
  • 5
  • 31
  • 53
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