51

I have defined a JavaScript variables called myData which is a new Array like this:

var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
             ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
             ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
             ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);

I am wondering if it is possible to sum the number values found in the array (ex. 0+0+21+2+0 and so on) and have probably a variable with the result that I can use outside of the script tag because I have 7 of this kind of arrays corresponding for each of the day in the week. I want to make a comparison afterwards based on that. That is the most preferred method for this kind of actions if is possible?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
Daniela costina Vaduva
  • 1,857
  • 5
  • 20
  • 22

11 Answers11

107

You could use the Array.reduce method:

const myData = [
  ['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
  ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
  ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
  ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]
];
const sum = myData
  .map( v => v[1] )                                
  .reduce( (sum, current) => sum + current, 0 );
  
console.log(sum);

See MDN

KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • It should be `prev[1]` I guess. By all means the result won't give `23`. – VisioN Apr 17 '13 at 10:40
  • 4
    @Kooilnc Please be aware that `Array.reduce` is an ECMAscript 5 addition so my not be supported by all browsers - see here https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce which also includes some code which can be implemented to overcome this – Mark Walters Apr 17 '13 at 10:41
  • 1
    @VisioN: forgot the initial value, added it. And no, it shouldn't be `prev[1]` @MarkWalters: yep, but one can use the shim from the MDN-link (see answer) – KooiInc Apr 17 '13 at 10:47
  • 1
    With an ES6 arrow function: `var sum = myData.reduce((sum, current) => (sum + current[1]), 0);` – rjmunro Sep 19 '16 at 16:06
58

I think the simplest way might be:

values.reduce(function(a, b){return a+b;})
ruhanbidart
  • 4,564
  • 1
  • 26
  • 13
  • 7
    This should be the accepted answer to the general question asked, but the poster had a data structure that would not work with this unfortunately. This is accurately the best way to handle an array of numbers though – netpoetica Dec 16 '14 at 03:28
  • 1
    Ensuring they are numbers wouldn't hurt: values.reduce(function(a, b){return +a + +b;}) – Fo. Aug 03 '15 at 01:59
  • 1
    @netpoetica `myData.map(function(o) { return o[1]; }).reduce(a, b) { return a + b; })` – Paolo Moretti Aug 14 '15 at 12:47
  • 1
    With EC6 this could look like `values.reduce((a + b) => a + b)` – hildende Oct 30 '15 at 20:54
18

Try the following

var myData = [['2013-01-22', 0], ['2013-01-29', 1], ['2013-02-05', 21]];

var myTotal = 0;  // Variable to hold your total

for(var i = 0, len = myData.length; i < len; i++) {
    myTotal += myData[i][1];  // Iterate over your first array and then grab the second element add the values up
}

document.write(myTotal); // 22 in this instance
jesterjunk
  • 2,342
  • 22
  • 18
Mark Walters
  • 12,060
  • 6
  • 33
  • 48
  • I think you meant `myData[i][1]`. And why use `parseFloat` if the value is already a number anyway? – Felix Kling Apr 17 '13 at 10:35
  • it output 24156 instead of like it should 3. I've tested with an "empty value array" and I receive the same output... – Daniela costina Vaduva Apr 17 '13 at 10:37
  • @FelixKling it works with `myData[i][1]` but how I make myTotal available in other script tag? – Daniela costina Vaduva Apr 17 '13 at 10:39
  • Daniel, did you fix the typo that Felix Kling pointed out? Rember to write "myData[i][1]" instead of the wrong version: "myData[1]" in the example. – Silas Hansen Apr 17 '13 at 10:39
  • @FelixKling Thanks have edited, and i guess i was being overprecautius by using parseFloat. Daniela i've tested and it works have a look here - http://jsbin.com/ibajas/1/ – Mark Walters Apr 17 '13 at 10:39
  • @DanielacostinaVaduva, To make it available to other script tags: Make sure that the variabele is global. This means its declaration (ie. "var mytotal") should occur right after the script tag and not in side any curley braces "{}". Also make sure that its loaded before the other script tags, else the variable wont be initialized. – Silas Hansen Apr 17 '13 at 10:42
13

I would use reduce

var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0], ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);

var sum = myData.reduce(function(a, b) {
    return a + b[1];
}, 0);

$("#result").text(sum);

Available on jsfiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
12

Creating a sum method would work nicely, e.g. you could add the sum function to Array

Array.prototype.sum = function(selector) {
    if (typeof selector !== 'function') {
        selector = function(item) {
            return item;
        }
    }
    var sum = 0;
    for (var i = 0; i < this.length; i++) {
        sum += parseFloat(selector(this[i]));
    }
    return sum;
};

then you could do

> [1,2,3].sum()
6

and in your case

> myData.sum(function(item) { return item[1]; });
23

Edit: Extending the builtins can be frowned upon because if everyone did it we would get things unexpectedly overriding each other (namespace collisions). you could add the sum function to some module and accept an array as an argument if you like. that could mean changing the signature to myModule.sum = function(arr, selector) { then this would become arr

lee penkman
  • 1,160
  • 15
  • 19
8

Or in ES6

values.reduce((a, b) => a + b),

example:

[1,2,3].reduce((a, b)=>a+b) // return 6
Jan Jarčík
  • 2,681
  • 2
  • 18
  • 21
2

If you want to discard the array at the same time as summing, you could do (say, stack is the array):

var stack = [1,2,3],
    sum = 0;
while(stack.length > 0) { sum += stack.pop() };
r3wt
  • 4,642
  • 2
  • 33
  • 55
btk
  • 3,158
  • 2
  • 29
  • 30
1

You can use the native map method for Arrays. map Method (Array) (JavaScript)

var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
             ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
             ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
             ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);
var a = 0;
myData.map( function(aa){ a += aa[1];  return a; });

a is your result

bjhamltn
  • 420
  • 5
  • 6
1

where 0 is initial value

Array.reduce((currentValue, value) => currentValue +value,0)

or

Array.reduce((currentValue, value) =>{ return currentValue +value},0)

or

[1,3,4].reduce(function(currentValue, value) { return currentValue + value},0)
Shahid Islam
  • 559
  • 3
  • 7
0

The javascript built-in reduce for Arrays is not a standard, but you can use underscore.js:

var data = _.range(10);
var sum = _(data).reduce(function(memo, i) {return memo + i});

which becomes

var sumMyData = _(myData).reduce(function(memo, i) {return memo + i[1]}, 0);

for your case. Have a look at this fiddle also.

Gismo Ranas
  • 6,043
  • 3
  • 27
  • 39
0

Old way (if you don't now the length of arguments/parameters)

 >> function sumla1(){

    result=0
    for(let i=0; i<arguments.length;i++){

        result+=arguments[i];

    }
    return result;
    }
    >> sumla1(45,67,88);
    >> 200

ES6 (destructuring of array)

>> function sumla2(...x){return x.reduce((a,b)=>a+b)}
>>
>> sumla2(5,5,6,7,8)
>>
>> 31
>>
>> var numbers = [4, 9, 16, 25];
>> sumla2(...numbers);
>> 54
Musa
  • 2,596
  • 26
  • 25