51

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.

0

9 Answers 9

81

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)
Sign up to request clarification or add additional context in comments.

2 Comments

i would double like this :)
@AntonSemenichenko this still suffers from known native pitfalls such as floating point arithmetic, so proceed with caution :)
62

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:

9 Comments

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.
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++)
@MarkByers what does << stand for?
@BeNdErR Left shift, it's binary operation. In his example he's shifing 0 to the left.
@BeNdErR and @RIYAJKHAN, the left shift << is used to convert the string elements to numerics so they can be added and not concatenated.
|
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);
})

2 Comments

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.
This is the closest to what I wanted. So.. does jQuery have a browser-independent reduce (like underscore?)? bugs.jquery.com/ticket/1886 - god this is amazingly stupid
28

Another method, if eval is safe & fast :

eval(["10","20","30","40","50"].join("+"))

3 Comments

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.
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.
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.
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"]);

3 Comments

Nice. I like your approach.
Change to r += parseInt(v); because "20" is a string not an integer.
Or parseFloat(v)
9
var total = 0;
$.each(someArray,function() {
    total += parseInt(this, 10);
});

2 Comments

The poster loaded each element as a string, so you'll either need to parseInt, parseFloat, or multiply by 1.
could also add a map in there to separate the parseInt, but don't think it'd gain much
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;
      };
    }

1 Comment

Thanks for including that ultra-simple solution to reuse Array.reduce. It worked great for me!
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);

2 Comments

Wasn't supported by IE8. Also will raise error if array is empty, better use .reduce(function(a,b){ return a+b; }, 0) which safely returns 0 on empty array.
Thanks @BeniCherniavsky-Paskin. i have updated my answer
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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.