1524

Given an array [1, 2, 3, 4], how can I find the sum of its elements? (In this case, the sum would be 10.)

I thought $.each might be useful, but I'm not sure how to implement it.

royhowie
  • 11,075
  • 14
  • 50
  • 67
akano1
  • 40,596
  • 19
  • 54
  • 67
  • 36
    @tereško Unwillingness to google is not a valid close reason on Stackoverflow. Please downvote if you feel that the question is not well (re)searched. (Also judging by the answers - this seems to be a highly controversial topic with many possible solutions including some highly upvoted bad practises (eval) - surprisingly.) – NoDataDumpNoContribution Jan 07 '16 at 10:26
  • 12
    Note: most answers here essentially compute `a[0] + a[1] + ...`, which can turn into string concatenation if the array has non-number elements. E.g. `['foo', 42].reduce((a,b)=>a+b, 0) === "0foo42"`. – Beni Cherniavsky-Paskin Jan 10 '16 at 17:00
  • 4
    No built in reducer one could feed to Array.reduce? Thinking something like `[1,2,3].reduce(Math.sum)`. – Phil Mar 24 '20 at 10:15

61 Answers61

1659

This'd be exactly the job for reduce.

If you're using ECMAScript 2015 (aka ECMAScript 6):

const sum = [1, 2, 3].reduce((partialSum, a) => partialSum + a, 0);
console.log(sum); // 6

For older JS:

const sum = [1, 2, 3].reduce(add, 0); // with initial value to avoid when the array is empty

function add(accumulator, a) {
  return accumulator + a;
}

console.log(sum); // 6

Isn't that pretty? :-)

joeljpa
  • 317
  • 2
  • 13
Florian Margaine
  • 58,730
  • 15
  • 91
  • 116
  • 80
    Assuming we all use ES2015, we can make it less verbose : `[1, 2, 3].reduce((a,b)=>a+b)` – Denys Séguret Apr 29 '15 at 15:35
  • Actually in lisp it would be more efficient to `(apply #'+ '(1 2 3))`. I am surprised that in JavaScript one can not do the same. I thought if I can `Math.max.apply(Math,[-12,-3.33,11,0,1])`, then why not `Math.sum.apply(Math,[-12,-3.33,11,0,1])`? – Oleg Shalaev Dec 07 '21 at 22:37
  • Is the second one backwards compatible for IE? – PauAI Aug 22 '22 at 22:01
  • @PauAI, IE is generally ES5 ("older JS") compliant. However, see https://css-tricks.com/a-business-case-for-dropping-internet-explorer. – isherwood Dec 12 '22 at 20:24
  • @DenysSéguret And assuming that we don't have an empty array, because that will throw: `Error: reduce of empty array with no initial value`. So it's better to initialize it with an initial value. – iTzVoko Jul 29 '23 at 10:53
1416

Recommended (reduce with default value)

Array.prototype.reduce can be used to iterate through the array, adding the current element value to the sum of the previous element values.

console.log(
  [1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
  [].reduce((a, b) => a + b, 0)
)

Without default value

You get a TypeError

console.log(
  [].reduce((a, b) => a + b)
)

Prior to ES6's arrow functions

console.log(
  [1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)

console.log(
  [].reduce(function(acc, val) { return acc + val; }, 0)
)

Non-number inputs

If non-numbers are possible inputs, you may want to handle that?

console.log(
  ["hi", 1, 2, "frog"].reduce((a, b) => a + b)
)

let numOr0 = n => isNaN(n) ? 0 : n

console.log(
  ["hi", 1, 2, "frog"].reduce((a, b) => 
    numOr0(a) + numOr0(b))
)

Non-recommended dangerous eval use

We can use eval to execute a string representation of JavaScript code. Using the Array.prototype.join function to convert the array to a string, we change [1,2,3] into "1+2+3", which evaluates to 6.

console.log(
  eval([1,2,3].join('+'))
)

//This way is dangerous if the array is built
// from user input as it may be exploited eg: 

eval([1,"2;alert('Malicious code!')"].join('+'))

Of course displaying an alert isn't the worst thing that could happen. The only reason I have included this is as an answer Ortund's question as I do not think it was clarified.

Stan Kurdziel
  • 5,476
  • 1
  • 43
  • 42
OwChallie
  • 14,933
  • 1
  • 10
  • 12
  • 25
    You do know that this magic with `reduce()` is still 25-30% slower than a simple indexed `for()` loop after long years? https://jsperf.com/reduce-vs-loop/4 – tevemadar Oct 29 '19 at 10:54
  • 1
    Some updated stats as of today using that page (via archive.org): - Chrome/Brave is 5-7% slower with reduce - Safari is 96%(!) slower with reduce - Firefox is 86% slower with reduce – Phoenix Sep 07 '22 at 16:50
  • @tevemadar Link returns `Error 500`; any new link to propose? – Joël Oct 25 '22 at 13:03
  • 1
    @Joël I've just put together something at https://jsbench.me/xal9odbag2/1 - but I don't know if I made a mistake, performance difference appears to be much higher than what I wrote about years ago. – tevemadar Oct 25 '22 at 15:38
270

Why not reduce? It's usually a bit counter intuitive, but using it to find a sum is pretty straightforward:

var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Casey Rodarmor
  • 14,878
  • 5
  • 30
  • 33
  • 4
    IE8 doesn't support it, and it doesn't look like jQuery intends on adding it. However, Prototype has it. – Ishmael Smyrnow Apr 10 '12 at 20:33
  • 5
    @Ishmael, you can use UnderscoreJS, which falls back to the browser's implementation if available, or implements its own otherwise. – Pablo D. Mar 13 '13 at 23:09
  • 1
    Very nice. Looking at the [execution time test](http://stackoverflow.com/a/12995054/1536976) of Riking, `reduce` also seems to be very efficient. – NoDataDumpNoContribution Jan 07 '16 at 12:53
  • 7
    What's counter-intuitive about `reduce()`? – canon Jan 07 '16 at 14:48
  • @canon: To get the sum, you would normally add all the numbers, instead of reducing them? – s4nji Jan 26 '16 at 16:46
  • 3
    @s4nji `Array.prototype.reduce()` _reduces_ an array to a single return value. – canon Jan 26 '16 at 16:56
  • 1
    @canon The meaning of (the word) reduce itself (without knowing what `Array.prototype.reduce()` does) is the opposite of (the word) adding, which is normally done to calculate a sum, therefore it is counter-intuitive. – s4nji Jan 26 '16 at 17:21
  • 7
    @s4nji ...unless you are reducing a sauce - in which case you are boling it down to its essentials, i.e. the sum of all flavors without the water overhead. :-) – CB Du Rietz Apr 24 '16 at 12:05
  • 3
    I can see how reduce is not intuitive in the given usage. You could not reasonably consider that reduce would work as an addition tool in the given case without the prior knowledge of how the function works. – CodingInTheUK May 13 '16 at 10:39
  • 1
    @canon [what-is-the-problem-with-reduce](http://stackoverflow.com/questions/181543/what-is-the-problem-with-reduce) – None Jun 28 '16 at 18:46
128
var arr = [1, 2, 3, 4];
var total = 0;
for (var i in arr) {
  total += arr[i];
}
Kartikey
  • 4,516
  • 4
  • 15
  • 40
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 3
    This is way faster than the jQuery.each() solution above. – Angry Dan Aug 24 '11 at 09:39
  • 51
    @Sprog: However, using `(var i=0; i – Riking Oct 21 '12 at 04:36
  • @Riking: Yay for micro-optimization! – Angry Dan Oct 22 '12 at 10:09
  • 16
    Using `for... in` loops on arrays works in this case _ coincidentally_ and because arrays extend objects. Riking's solution is better – Benjamin Gruenbaum May 07 '13 at 03:29
  • for..in loops are the most expensive loops, so its important to keep that in mind and use them ONLY when needed, in this case you can easily set local variables for the index and array length. then use while or for to loop through the array outputting the value like arr[index] – Josh Bedo Feb 24 '14 at 14:31
  • 2
    @BenjaminGruenbaum provided that nothing has added enumerable properties to array's prototype... – canon Jan 07 '16 at 14:47
  • I'm no javascript guru but ... doesn't `i` takes the array's values, not indexes? – YSC Jan 07 '16 at 16:45
  • 1
    @YSC no, it does not. A `for...in` loop in JavaScript takes the indices, which is a common stumbling block for coders that expect to get the values. (Try `for(var i in [1,2,3]) { console.log(i); }` in a console.) – Amber Jan 10 '16 at 02:52
  • 1
    http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea – Evan Trimboli May 24 '16 at 21:17
  • @YSC A `for...in` loop accesses the indices in arrays or keys in objects. If you want to access the values directly, you can use a `for...of` loop with arrays or other iterable objects like strings but it doesn't work with objects. For objects, you'll need to use `for...in` to access the keys and then get the values from there. – AlwaysLearning Oct 30 '21 at 21:01
60
var total = 0;
$.each(arr,function() {
    total += this;
});
Tyler Carter
  • 60,743
  • 20
  • 130
  • 150
  • 108
    Please, please, please use the answer with `reduce` below; do not declare mutable vars when you do not have too. – Bruno Grieder Feb 27 '15 at 14:29
  • 11
    This answer is under [meta discussion](http://meta.stackoverflow.com/q/314157/871050) – Madara's Ghost Jan 07 '16 at 10:24
  • 13
    Please do not use this, even though it is the "accepted answer"; the answer by Florian below is much better! – Andy Sinclair Jan 07 '16 at 14:13
  • 4
    jQuery's `$.each()` and friends were a win (if you're OK with the dependency of course) before JS arrays gained builtin `.reduce()`, `.forEach()` etc. Nowdays the builtin `reduce` is clearly the one *idiomatic* way to write it; if you still want to support IE8 which lacks `.reduce` (and don't want a polyfill), I'd say fall back to a `for` loop. – Beni Cherniavsky-Paskin Jan 10 '16 at 12:00
  • 18
    @BrunoGrieder "Do not declare mutable vars when you do not have to" is an extremely biased opinion about an *imperative language*, it is hardly a code smell by any stretch of the imagination. There's absolutely nothing wrong with Tyler's answer, and the only difference between Tyler's and Florian's is style. – Rob Jan 11 '16 at 09:43
  • 6
    From OP: _I thought $.each might be useful, but I'm not sure how to implement it._ This maybe not be the best, but answer the OP's request. –  Jan 11 '16 at 15:30
  • 8
    The criticisms to this answer are ridiculous. The question specifically tags jquery and asks about $.each. Is reduce the right answer for most people asking this question? Of course it is, but that's why we have multiple answers and brains to evaluate them against our specific use case. – aw04 Oct 17 '16 at 14:37
  • 1
    I think the amount of controversy this caused 7 years after it was written is hilarious. – Tyler Carter Sep 30 '19 at 10:47
58

Anyone looking for a functional oneliner like me?

Assuming:

const arr = [1, 2, 3, 4];

Here's the oneliner for modern JS:

sum = arr.reduce((a, b) => a + b, 0);

(If you happen to have to support ye olde IE without arrow functions:)

sum = arr.reduce(function (a, b) {return a + b;}, 0);

Note that 0 is the initial value here, so you can use that as offset if needed. Also note that this initial value is needed, otherwise calling the function with an empty array will error.

geek-merlin
  • 1,720
  • 17
  • 13
53

If you happen to be using Lodash you can use the sum function

array = [1, 2, 3, 4];
sum = _.sum(array); // sum == 10
simhumileco
  • 31,877
  • 16
  • 137
  • 115
David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122
  • Work well with Typescript too. – Greg Herbowicz Apr 17 '21 at 16:52
  • Whats with these answers? He did not tag lodash, and there is many better answers above. Furthermore, this is kind of like saying "If you happen to be using python, you can do this". – Blaze612 YT Jun 02 '22 at 02:08
  • @LastTribunal I was just saying that these answers should be a comment, as they aren't full answers, just like of you happen to be using something. – Blaze612 YT Jul 07 '22 at 04:56
37

This is possible by looping over all items, and adding them on each iteration to a sum-variable.

var array = [1, 2, 3];

for (var i = 0, sum = 0; i < array.length; sum += array[i++]);

JavaScript doesn't know block scoping, so sum will be accesible:

console.log(sum); // => 6

The same as above, however annotated and prepared as a simple function:

function sumArray(array) {
  for (
    var
      index = 0,              // The iterator
      length = array.length,  // Cache the array length
      sum = 0;                // The total amount
      index < length;         // The "for"-loop condition
      sum += array[index++]   // Add number on each iteration
  );
  return sum;
}
yckart
  • 32,460
  • 9
  • 122
  • 129
  • 14
    While clever, I'd find code declaring `sum` outside the loop much more readable. – Beni Cherniavsky-Paskin Jan 05 '16 at 13:57
  • 1
    @BeniCherniavsky-Paskin Yeah, same here... Don't know why I did it this way that day... However, I'll let it as it is! It's just an example of *how we might could...* ;) – yckart Jan 05 '16 at 14:19
  • Since ES6, javascript DOES know block scoping with `const` and `let`. So you can declare `sum` outside the `for` loop as `let sum = 0;`. You can also cache the array length before the loop as `const length = array.length;` – KSK Nov 22 '17 at 01:35
28
arr.reduce(function (a, b) {
    return a + b;
});

Reference: Array.prototype.reduce()

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
onhout
  • 297
  • 3
  • 3
21

OK, imagine you have this array below:

const arr = [1, 2, 3, 4];

Let's start looking into many different ways to do it as I couldn't find any comprehensive answer here:

1) Using built-in reduce()

function total(arr) {
  if(!Array.isArray(arr)) return;
  return arr.reduce((a, v)=>a + v);
}

2) Using for loop

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0;
  for (let i=0,l=arr.length; i<l; i++) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

3) Using while loop

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0, i=-1;
  while (++i < arr.length) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

4) Using array forEach

function total(arr) {
  if(!Array.isArray(arr)) return;
  let sum=0;
  arr.forEach(each => {
    sum+=each;
  });
  return sum;
};

and call it like this:

total(arr); //return 10

It's not recommended to prototype something like this to Array...

Alireza
  • 100,211
  • 27
  • 269
  • 172
16

You can try the following code:

[1, 2, 3, 4].reduce((pre,curr)=>pre+curr,0)
Md.Shakil Shaikh
  • 347
  • 4
  • 11
13

You can also use reduceRight.

[1,2,3,4,5,6].reduceRight(function(a,b){return a+b;})

which results output as 21.

Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight

Rohit Bhalke
  • 147
  • 1
  • 5
  • Should be faster in chrome because the optimization to javascript looping (i.e. decrementing the length) can also be applied to the underlying assembly to make it run faster. – Jack G Mar 13 '17 at 19:01
11

A standard JavaScript solution:

var addition = [];
addition.push(2);
addition.push(3);

var total = 0;
for (var i = 0; i < addition.length; i++)
{
    total += addition[i];
}
alert(total);          // Just to output an example
/* console.log(total); // Just to output an example with Firebug */

This works for me (the result should be 5). I hope there is no hidden disadvantage in this kind of solution.

nano
  • 127
  • 1
  • 2
11

TL;DR

If you care about performance, define a function that uses a for-loop.

function sum(arr) {
    var res = 0;
    for (var x of arr) {
        res += x;
    }
    return res;
}

Benchmark

I benchmarked a selection of implementations using benchmark.js (typescript version):

const arr = Array.from({ length: 100 }, () => Math.random());
const reducer = function (p: number, a: number) {
    return p + a;
};
const recursion = function (arr: number[], i: number) {
    if(i > 0) return arr[i] + recursion(arr, i - 1)
    else return 0
};
const recursion2 = function (arr: number[], i: number, len: number) {
    if(i < len) return arr[i] +  recursion2(arr, i + 1, len)
    else return 0
};
const recursion3 = function (arr: number[], i: number) {
    if(i < arr.length) return arr[i] + recursion3(arr, i + 1)
    else return 0
};
new Benchmark.Suite()
    .add("jquery", () => {
        let res = 0;
        $.each(arr, (_, x) => (res += x));
    })
    .add("lodash", ()=>_.sum(arr))
    .add("forEach", () => {
        let res = 0;
        arr.forEach((x) => (res += x));
    })
    .add("reduce", () => arr.reduce((p, a) => p + a, 0))
    .add("predefined reduce", () => arr.reduce(reducer, 0))
    .add("eval", () => eval(arr.join("+")))
    .add("recursion", () => recursion(arr, arr.length - 1))
    .add("recursion2", () => recursion2(arr, 0, arr.length))
    .add("recursion3", () => recursion3(arr, 0))
    .add("naive", () => (
        arr[0]+arr[1]+arr[2]+arr[3]+arr[4]+arr[5]+arr[6]+arr[7]+arr[8]+arr[9]+
        arr[10]+arr[11]+arr[12]+arr[13]+arr[14]+arr[15]+arr[16]+arr[17]+arr[18]+arr[19]+
        arr[20]+arr[21]+arr[22]+arr[23]+arr[24]+arr[25]+arr[26]+arr[27]+arr[28]+arr[29]+
        arr[30]+arr[31]+arr[32]+arr[33]+arr[34]+arr[35]+arr[36]+arr[37]+arr[38]+arr[39]+
        arr[40]+arr[41]+arr[42]+arr[43]+arr[44]+arr[45]+arr[46]+arr[47]+arr[48]+arr[49]+
        arr[50]+arr[51]+arr[52]+arr[53]+arr[54]+arr[55]+arr[56]+arr[57]+arr[58]+arr[59]+
        arr[60]+arr[61]+arr[62]+arr[63]+arr[64]+arr[65]+arr[66]+arr[67]+arr[68]+arr[69]+
        arr[70]+arr[71]+arr[72]+arr[73]+arr[74]+arr[75]+arr[76]+arr[77]+arr[78]+arr[79]+
        arr[80]+arr[81]+arr[82]+arr[83]+arr[84]+arr[85]+arr[86]+arr[87]+arr[88]+arr[89]+
        arr[90]+arr[91]+arr[92]+arr[93]+arr[94]+arr[95]+arr[96]+arr[97]+arr[98]+arr[99]))
    .add("loop with iterator", () => {
        let res = 0;
        for (const x of arr) res += x;
    })
    .add("traditional for loop", () => {
        let res = 0;
        // cache the length in case the browser can't do it automatically
        const len = arr.length;
        for (let i = 0; i < len; i++) res += arr[i];
    })
    .add("while loop", () => {
        let res = 0;
        let i = arr.length;
        while (i--) res += arr[i];
    })
    .add("loop in a function ", () => sum(arr))
    .on("cycle", (event) => console.log(String(event.target)))
    .run();

In chrome 104, the for-loop-based implementations are the fastest:

jquery               x  1,832,472 ops/sec ±1.35% (61 runs sampled)
lodash               x  2,079,009 ops/sec ±1.11% (68 runs sampled)
forEach              x  4,887,484 ops/sec ±2.35% (67 runs sampled)
reduce               x 21,762,391 ops/sec ±0.46% (69 runs sampled)
predefined reduce    x  2,026,411 ops/sec ±0.50% (68 runs sampled)
eval                 x     33,381 ops/sec ±2.54% (66 runs sampled)
recursion            x  2,252,353 ops/sec ±2.13% (62 runs sampled)
recursion2           x  2,301,516 ops/sec ±1.15% (65 runs sampled)
recursion3           x  2,395,563 ops/sec ±1.65% (66 runs sampled)
naive                x 31,244,240 ops/sec ±0.76% (66 runs sampled)
loop with iterator   x 29,554,762 ops/sec ±1.07% (66 runs sampled)
traditional for loop x 30,052,685 ops/sec ±0.67% (66 runs sampled)
while loop           x 18,624,045 ops/sec ±0.17% (69 runs sampled)
loop in a function   x 29,437,954 ops/sec ±0.54% (66 runs sampled)

Firefox 104 shows similar behaviour:

jquery               x  1,461,578 ops/sec ±1.58% (64 runs sampled)
lodash               x  4,931,619 ops/sec ±0.80% (66 runs sampled)
forEach              x  5,594,013 ops/sec ±0.51% (68 runs sampled)
reduce               x  3,731,232 ops/sec ±0.53% (66 runs sampled)
predefined reduce    x  2,633,652 ops/sec ±0.54% (66 runs sampled)
eval                 x    105,003 ops/sec ±0.88% (66 runs sampled)
recursion            x  1,194,551 ops/sec ±0.24% (67 runs sampled)
recursion2           x  1,186,138 ops/sec ±0.20% (68 runs sampled)
recursion3           x  1,191,921 ops/sec ±0.24% (68 runs sampled)
naive                x 21,610,416 ops/sec ±0.66% (66 runs sampled)
loop with iterator   x 15,311,298 ops/sec ±0.43% (67 runs sampled)
traditional for loop x 15,406,772 ops/sec ±0.59% (67 runs sampled)
while loop           x 11,513,234 ops/sec ±0.60% (67 runs sampled)
loop in a function   x 15,417,944 ops/sec ±0.32% (68 runs sampled)

Discussion

Implementations defining an anonymous function are generally slower because creating an anonymous function is a significant overhead. When running the benchmark with a large array, e.g., with length 1000 instead of 100, the difference between reduce and the for-loop-based implementations becomes insignificant in chrome.

Chrome's V8 engine knows how to inline simple anonymous functions in reduce since the reduce test case is much faster than the predefined reduce test case. Firefox seems to try something similar but is less efficient in doing so. Non-inlined function calls are pretty slow in js since the call stack is less efficient than the call stack in compiled software.

Similar to reduce, the forEach- and jquery-based implementations use anonymous functions and are relatively slow. lodash has a specialized sum implementation, but it is (as of v4.0.0) implemented as a special case of sumBy, which is relatively inefficient.

eval is the by far slowest test case. This makes sense since constructing the string using concatenations might cause several dynamic allocations (which are slow). Next, the parser has to be invoked and only then can the code be finally executed.

I've included some recursive implementations because some people on the internet claim that recursion is faster than loops in js. I can't reproduce their example - using benchmark.js, recursion is very slow, and when using console.time with a loop, both functions take the same time. When calculating the sum, as expected, recursion is much slower than loops, probably due to intense usage of the js call stack.

The naive implementation would be manually adding all 100 elements of the array. While being quite inconvenient, this is the fastest implementation. But, luckily, for-loops come very close. Adding a single function call around the loop doesn't harm the performance. Therefore, you can feel free to use the utility function from above.

I have no explanation why the while loop is slower than the for loop. Iterating the array in reverse doesn't seem to be the problem here.

Corylus
  • 736
  • 5
  • 16
10

Funny approach:

eval([1,2,3].join("+"))
electron
  • 801
  • 8
  • 18
  • 7
    Please could you expand on this answer by explaining what is happening in this code? Why does it work? What does it do exactly? These things help to improve the quality of the answer. – Ortund Oct 21 '16 at 08:54
  • @user40521 has already answered this the way i think. I didn't see it. – electron Oct 21 '16 at 09:34
  • While this is short and sweet, and certainly interesting, it is also very inefficient. Using `reduce` is definitely preferable for the majority, if not all, cases. – Ninjakannon Jan 15 '18 at 10:45
  • Errm, `[1,"2;YourProgram.ripToShreds();3",4]` – Radvylf Programs Oct 25 '18 at 12:22
  • So I'm getting `NaN` when trying `eval(['alert("removing your computer")',2,3].join("+"))` wrong answer 0/10 – Adam Pietrasiak Mar 27 '19 at 08:54
9

I am a beginner with JavaScript and coding in general, but I found that a simple and easy way to sum the numbers in an array is like this:

    var myNumbers = [1,2,3,4,5]
    var total = 0;
    for(var i = 0; i < myNumbers.length; i++){
        total += myNumbers[i];
    }

Basically, I wanted to contribute this because I didn't see many solutions that don't use built-in functions, and this method is easy to write and understand.

Community
  • 1
  • 1
  • 2
    How is this any different from [this 2012 answer](http://stackoverflow.com/a/12228538/1269037) or [this 2014 answer](http://stackoverflow.com/a/27336090/1269037)? There's two solutions you haven't seen. – Dan Dascalescu Feb 09 '17 at 06:58
7

Use a for loop:

const array = [1, 2, 3, 4];
let result = 0;

for (let i = 0; i < array.length - 1; i++) {
  result += array[i];
}

console.log(result); // Should give 10

Or even a forEach loop:

const array = [1, 2, 3, 4];
let result = 0;

array.forEach(number => {
  result += number;
})

console.log(result); // Should give 10

For simplicity, use reduce:

const array = [10, 20, 30, 40];
const add = (a, b) => a + b
const result = array.reduce(add);

console.log(result); // Should give 100
Hunter
  • 3,080
  • 20
  • 23
6

A few people have suggested adding a .sum() method to the Array.prototype. This is generally considered bad practice so I'm not suggesting that you do it.

If you still insist on doing it then this is a succinct way of writing it:

Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}

then: [1,2].sum(); // 3

Note that the function added to the prototype is using a mixture of ES5 and ES6 function and arrow syntax. The function is declared to allow the method to get the this context from the Array that you're operating on. I used the => for brevity inside the reduce call.

Guy
  • 65,082
  • 97
  • 254
  • 325
  • If you're going to mess with prototypes (and you shouldn't), a `Math.prototype.sum` method would be more appropriate. – Joe Maffei May 23 '22 at 20:38
6

ES6 for..of

let total = 0;

for (let value of [1, 2, 3, 4]) {
    total += value; 
}
caiohamamura
  • 2,260
  • 21
  • 23
5

A short piece of JavaScript code would do this job:

var numbers = [1,2,3,4];
var totalAmount = 0;

for (var x = 0; x < numbers.length; x++) {

    totalAmount += numbers[x];
}

console.log(totalAmount); //10 (1+2+3+4)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
5
var totally = eval(arr.join('+'))

That way you can put all kinds of exotic things in the array.

var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]

I'm only half joking.

user40521
  • 1,997
  • 20
  • 8
5

Use reduce

let arr = [1, 2, 3, 4];

let sum = arr.reduce((v, i) => (v + i));

console.log(sum);
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Damien
  • 1,582
  • 1
  • 13
  • 24
5

No need to initial value! Because if no initial value is passed, the callback function is not invoked on the first element of the list, and the first element is instead passed as the initial value. Very cOOl feature :)

[1, 2, 3, 4].reduce((a, x) => a + x) // 10
[1, 2, 3, 4].reduce((a, x) => a * x) // 24
[1, 2, 3, 4].reduce((a, x) => Math.max(a, x)) // 4
[1, 2, 3, 4].reduce((a, x) => Math.min(a, x)) // 1
Yas
  • 4,957
  • 2
  • 41
  • 24
5

Here's an elegant one-liner solution that uses stack algorithm, though one may take some time to understand the beauty of this implementation.

const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);

getSum([1, 2, 3, 4, 5]) //15

Basically, the function accepts an array and checks whether the array contains exactly one item. If false, it pop the last item out of the stack and return the updated array.

The beauty of this snippet is that the function includes arr[0] checking to prevent infinite looping. Once it reaches the last item, it returns the entire sum.

Rex Low
  • 2,069
  • 2
  • 18
  • 47
5

Accuracy

Sort array and start sum form smallest numbers (snippet shows difference with nonsort)

[...arr].sort((a,b)=>a-b).reduce((a,c)=>a+c,0)

arr=[.6,9,.1,.1,.1,.1]

sum     =                       arr.reduce((a,c)=>a+c,0)
sortSum = [...arr].sort((a,b)=>a-b).reduce((a,c)=>a+c,0)

console.log('sum:     ',sum);
console.log('sortSum:',sortSum);
console.log('sum==sortSum :', sum==sortSum);

// we use .sort((a,b)=>a-b) instead .sort() because
// that second one treat elements like strings (so in wrong way)
// e.g [1,10,9,20,93].sort() -->  [1, 10, 20, 9, 93]

For multidimensional array of numbers use arr.flat(Infinity)

arr= [ [ [1,2,3,4],[1,2,3,4],[1,2,3,4] ],
       [ [1,2,3,4],[1,2,3,4],[1,2,3,4] ] ];
      
sum = arr.flat(Infinity).reduce((a,c)=> a+c,0);

console.log(sum);  // 60
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
5

Simplest answer to understand underlying process:

let array = [10, 20, 30, 40, 50]
let total = 0

for(let i in array)
{
    total += array[i]
}

console.log(total)

& if you're already familiar with underlying process then built-in method can save you time:

let array = [10, 20, 30, 40, 50]
let total = array.reduce((x, y) => x + y)
console.log(total)
Shoaib Khalil
  • 1,874
  • 17
  • 10
5

Is there a reason not to just filter the array first to remove non-numbers? Seems simple enough:

[1, 2, 3, null, 'a'].filter((x) => !isNaN(x)).reduce((a, b) => a + b)
Morrious
  • 179
  • 1
  • 12
4

Those are really great answers, but just in case if the numbers are in sequence like in the question ( 1,2,3,4) you can easily do that by applying the formula (n*(n+1))/2 where n is the last number

Santosh
  • 1,027
  • 13
  • 12
  • Totally agree, this is the most effective way if array numbers are in sequence. Gauss & Consecutive Numbers formula var array = [1, 2, 3, 4]; var n = array.length; var sum = n/2 * (1+4) – Kirill A Aug 27 '21 at 15:10
4

You can combine reduce() method with lambda expression:

[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);
antonjs
  • 14,060
  • 14
  • 65
  • 91
4

With reduce()

[1, 2, 3, 4].reduce((a, b) => a + b, 0); // 10

With forEach()

let sum = 0;
[1, 2, 3, 4].forEach(n => sum += n);
sum; // 10

With Parameter

function arrSum(arr) { 
  sum = 0;  
  arr.forEach(n => sum += n); 
  return sum; 
}

arrSum([1, 2, 3, 4]) // 10
Ahmad Moghazi
  • 1,419
  • 13
  • 15
3

i saw all answers going for 'reduce' solution

var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
    total += array[i]
}
console.log(total)
Adrian Swifter
  • 99
  • 1
  • 2
  • 9
3

very simple

step 1 we should have an array like :

const arrayNumber = [500,152,154,1555,12445];

step 2 (you can ignore this step if) step is to be sur that all values in table are number for that

let newArray = [];
for (let i = 0; i < arrayNumber.length; i++) {
        newArray.push(parseInt(arrayNumber[i], 10));
      }

step 3

const sumInArray = dataData.reduce( (a, b) => a + b);

finally

console.log(sumInArray);
bahri noredine
  • 731
  • 9
  • 15
3
getTotal = (arr) => {
    let total = 0
    for (let i = 0; i < arr.length; i++) {
        total += arr[i];
    }
    return total
}

getTotal([1, 2, 3, 4]) // 10
getTotal([1, 2, 3, 4, 5]) // 15

Sharjeel Faiq
  • 87
  • 1
  • 9
2

Cool tricks here, I've got a nit pick with a lot of the safe traditional answers not caching the length of the array.

function arraySum(array){
  var total = 0,
      len = array.length;

  for (var i = 0; i < len; i++){
    total += array[i];
  }

  return total;
};

var my_array = [1,2,3,4];

// Returns 10
console.log( arraySum( my_array ) );

Without caching the length of the array the JS compiler needs to go through the array with every iteration of the loop to calculate the length, it's unnecessary overhead in most cases. V8 and a lot of modern browsers optimize this for us, so it is less of a concern then it was, but there are older devices that benefit from this simple caching.

If the length is subject to change, caching's that could cause some unexpected side effects if you're unaware of why you're caching the length, but for a reusable function who's only purpose is to take an array and add the values together it's a great fit.

Here's a CodePen link for this arraySum function. http://codepen.io/brandonbrule/pen/ZGEJyV

It's possible this is an outdated mindset that's stuck with me, but I don't see a disadvantage to using it in this context.

  • The issue of caching the length is a red herring. JS engines will optimize this for you without blinking. –  Jan 10 '16 at 17:06
2
Object.defineProperty(Object.prototype, 'sum', {
    enumerable:false,
    value:function() {
        var t=0;for(var i in this)
            if (!isNaN(this[i]))
                t+=this[i];
        return t;
    }
});

[20,25,27.1].sum()                 // 72.1
[10,"forty-two",23].sum()          // 33
[Math.PI,0,-1,1].sum()             // 3.141592653589793
[Math.PI,Math.E,-1000000000].sum() // -999999994.1401255

o = {a:1,b:31,c:"roffelz",someOtherProperty:21.52}
console.log(o.sum());              // 53.519999999999996
ostranenie
  • 37
  • 2
  • Does this code remove your operating system? Or does it send your personal information to me? –  Sep 09 '17 at 12:21
2

This is much easier

function sumArray(arr) {
    var total = 0;
    arr.forEach(function(element){
        total += element;
    })
    return total;
}

var sum = sumArray([1,2,3,4])

console.log(sum)
Jakub Gawel
  • 63
  • 1
  • 6
2

With ES6 rest parameter

let array = [1, 2, 3, 4]

function sum(...numbers) {
    let total = 0;
    for (const number of numbers) {
        total += number;
    }
    return total;
}

console.log(sum(...array));
cdavis
  • 171
  • 1
  • 6
  • Note that given a large array this will give stack overflow exceptions (spread operator in general is can result in this with large inputs) – Colin D Nov 02 '19 at 03:36
2

A simple method example:

function add(array){
    var arraylength = array.length;
    var sum = 0;
    for(var timesToMultiply = 0; timesToMultiply<arraylength; timesToMultiply++){
        sum += array[timesToMultiply];
    }

    return sum;
}

console.log(add([1, 2, 3, 4]));
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
2

When the array consists of strings one has to alter the code. This can be the case, if the array is a result from a databank request. This code works:

alert(
["1", "2", "3", "4"].reduce((a, b) => Number(a) + Number(b), 0)
);

Here, ["1", "2", "3", "4"] ist the string array and the function Number() converts the strings to numbers.

feli_x
  • 149
  • 1
  • 8
2

You can get the sum using for of loop like following:

let arr = [1, 2, 3, 4];
let total = 0;
for (let i of arr) {
  total += i;
}
console.log(total)
Abhishek Kumar
  • 955
  • 11
  • 11
1

try this...

function arrSum(arr){
    total = 0;  
    arr.forEach(function(key){
        total = total + key;            
    });
    return total;
}
Sushil
  • 2,324
  • 1
  • 27
  • 26
1

Vanilla JavaScript is all you need:

> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(function(e){sum += e}); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(e => sum += e); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e in a) sum += e; sum
"00123foobar"
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e of a) sum += e; sum
10
Cees Timmerman
  • 17,623
  • 11
  • 91
  • 124
1

This function can sum up all the numbers -

 function array(arr){
   var sum = 0;
   for (var i = 0; i< arr.length; i++){
    sum += arr[i];
   }
   console.log(sum);
 }
 array([5, 1, 3, 3])
MRIDUAVA
  • 141
  • 1
  • 4
1

Considering you have the array

const arr = [1, 2, 3, 4];

For me, the most intuitive way is using a for-in

let sum = 0;
for(var value in arr) {
    sum += arr[value];
}

console.log('Array:', arr);
console.log('Sum:', sum);

Yet, you can also use Arrow Functions and the reduce function

const sum = arr.reduce(function (a, b) {
    return a + b;
}, 0);

console.log('Array:', arr);
console.log('Sum:', sum);

They're both gonna output

Array: [ 1, 2, 3, 4]
Sum: 10
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
0

Just use this function:

function sum(pArray)
{
  pArray = pArray.reduce(function (a, b) {
      return a + b;
  }, 0);

  return pArray;
}

function sum(pArray)
{
  pArray = pArray.reduce(function (a, b) {
      return a + b;
  }, 0);

  return pArray;
}

var arr = [1, 4, 5];

console.log(sum(arr));
Black
  • 18,150
  • 39
  • 158
  • 271
0

A "duplicate" question asked how to do this for a two-dimensional array, so this is a simple adaptation to answer that question. (The difference is only the six characters [2], 0, which finds the third item in each subarray and passes an initial value of zero):

const twoDimensionalArray = [
  [10, 10, 1],
  [10, 10, 2],
  [10, 10, 3],
];
const sum = twoDimensionalArray.reduce( (partial_sum, a) => partial_sum + a[2], 0 ) ; 
console.log(sum); // 6
Cat
  • 4,141
  • 2
  • 10
  • 18
0

You can try this:

var arr = [100,114,250,1200];
var total = 0; 
for(var i in arr){
  total += parseInt(arr[i]);
}

console.log(total);

Output will be: 1664

Or if value is Float, then try this:

var arr = [100.00,114.50,250.75,1200.00];
    var total = 0; 
    for(var i in arr){
      total += parseFloat(arr[i]);
    }
    
    console.log(total.toFixed(2));

Output will be: 1665.25

Faridul Khan
  • 1,741
  • 1
  • 16
  • 27
0

I´m aware that this is an old post. But I just wanted to share my approach to the problem.

let myArr = [1, 3, 4, 5, 6, 7, 8];
let counter = 0;
for(let i = 0; i < myArr.length; i++){
  counter = counter + myArr[i];
    console.log(counter);}
Robert CG
  • 19
  • 6
0
//Try this way

const arr = [10,10,20,60]; 
const sumOfArr = (a) =>{
    let sum=0;
    for(let i in a) { 
        sum += a[i];
    }
    return sum;
}
console.log(sumOfArr(arr))
Force Bolt
  • 1,117
  • 9
  • 9
0

No one mentioned functional programming, but it would be very clean approach to use Ramda in this case:

//Assuming you use nodejs, but can also be used in browser
const R = require('ramda');

let nums = [2, 4, 6, 8, 10];
console.log(R.sum(nums));
valerii15298
  • 737
  • 4
  • 15
0

The truth is there is an old and funny classic solution (beside newbie 'foreach' and 'reduce'): the classic for of.

y = 0;
for (x of [1, 2, 3, 4]) y+=x;
Mityu
  • 143
  • 1
  • 8
0

I see that this is an old question, but hardly any of the answers actually use jQuery and specifically $.each as requested by the asker. There is a way to do this, but the native approaches as suggested by many (i.e. using Array.reduce()) are much better and easier.

Here's the jQuery way if you absolutely have to use it:

  var arr = [1,2,3,4];
  var sum = 0;
  
  $.each( arr, (i, v) => sum += v);

  alert(sum); // This will be 10
aalaap
  • 4,145
  • 5
  • 52
  • 59
0

i think this is the simple way to find sum array of numbers

function sumArray(arr){

    let total = 0;

    for(i = 0; i<arr.length ; i++){

        total += arr[i];
    }
    return total;
}

console.log(sumArray([1,2,3,4,]));

0
const a = [1,'2',3,100,'200','text'];
var total= 0;
let b = a.filter( value => !Number.isNaN(Number(value)) );
for(let c in b)
{
  total += Number(b[c]);
}
console.log(total)
//output:306
ramin
  • 448
  • 4
  • 15
0
// 1:
const numbers = new Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
// Or const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let sum = numbers.reduce(
  (accumulator, currentValue) => accumulator + currentValue
);
console.log(sum);
// 2:
sum = 0;
for (const number of numbers) {
  sum += number;
}
console.log(sum);
// 3:
sum = 0;
for (const index in numbers) {
  sum += numbers[index];
}
console.log(sum);
// 4:
sum = 0;
for (let index = 0; index < numbers.length; index++) {
  sum += numbers[index];
}
console.log(sum);
// 5:
sum = 0;
numbers.forEach((num) => (sum += num));
console.log(sum);
// ;)
Saj
  • 189
  • 1
  • 2
-2

Use recursion

var sum = (arr) => arr.length === 1 ? arr[0] : arr.shift() + sum(arr);
sum([1,2,3,4]) // 10
Giffo
  • 4,161
  • 3
  • 15
  • 16
-2

In addition, sum with es6 for simple array.

const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a,0);
 
console.log(sum); 

For object array with default initialize value

const totalAmount = obj => 
    Object.values(obj).reduce((acc, { order_qty, mrp_price }) => 
    acc + order_qty * mrp_price, 0);
    
    console.log(totalAmount); 
Majedur
  • 3,074
  • 1
  • 30
  • 43
-2

Someone also can use map() function for the summation of an array values.

function sumOfArrVal(arr){
    let sum=0;
    arr.map(val=>sum+=val)
    return sum
}

let result=sumOfArrVal([1,2,3,4])
console.log(result)
Md.Shakil Shaikh
  • 347
  • 4
  • 11
  • Since map builds a new array, using it when you aren't using the returned array is an anti-pattern. In this case you should use .reduce instead – Ghostrydr Apr 06 '22 at 14:45
-3

For really large numbers cycling or reducing could be process intensive. What about using Gauss?

sum = (n * (n+1))/2;

From mathcentral.

cramopy
  • 3,459
  • 6
  • 28
  • 42
MangoHeat
  • 1
  • 3
  • 1
    This only works for sequential arrays starting at 1, with a step of 1. Granted, the OPs question includes an example which may be confusing, since [1, 2, 3, 4] fits the bill. But what if we want to sum this one: [1, 7, 21, 10009, 300198] ? – Silviu Preda Jan 16 '18 at 12:40
-6
    <!DOCTYPE html>
    <html>
    <body>

      <p>Click the button to join two arrays.</p>
      <button onclick="myFunction()">Try it</button>
      <p id="demo"></p>
    <script>
var hege = [1, 2,4,6,7,8,8];
var stale = [1, 2,4,5];
function myFunction() {
    console.log((hege.length > stale.length))    
    var children  = (hege.length > stale.length)? abc1() :abc2();       document.getElementById("demo").innerHTML = children;
}
function abc1(){
    console.log(hege,"Abc1")    
    var abcd=hege.map(function (num, idx) {
        console.log(hege.length , idx)
        return stale.length>idx?num + stale[idx]:num;
    })
    return abcd;
}

function abc2(){

    console.log(hege,"Abc2",stale)    
    var abcd=stale.map(function (num, idx) {
        console.log(hege.length , idx)
        return hege.length>idx?num + hege[idx]:num;
    })
    return abcd;
}
</script>

</body>
</html>
-14

Use map:

var sum = 0;
arr.map(function(item){
    sum += item;
});

// sum now contains the total.

You could potentially add the method to the Array prototype.

Array.prototype.sum = function(){
    var sum = 0;
    this.map(function(item){
        sum += item;
    });
    return sum;
}

Then you can use it on any Array like so:

arr.sum();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Capstone
  • 2,254
  • 2
  • 20
  • 39
  • 29
    That's because it's _wrong_ to use _map_ in this case. map _maps_ array elements somewhere, what you're looking for if you want to be functional is _reduce_ – Benjamin Gruenbaum May 07 '13 at 03:25
  • Who said anything about being functional? Or do you mean functional in the sense of being useful? – Capstone May 07 '13 at 04:58
  • 14
    `forEach` should be used instead of `map` in this case. – Oleg May 25 '13 at 16:09
  • 2
    Extending the prototype of built-in objects is bad in my opinion. Use a separate utility class for methods like these or some other method. – oldwizard Oct 15 '15 at 10:43
  • At this point I think the realistic answers have been added above, but I think this is useful for completeness ;) It's still better than the accepted answer. Of course you could also extend the prototype of jQuery, just for fun. – MrMowgli Jan 07 '16 at 10:54
  • 2
    You're using `map()` improperly. It's supposed to be used to generate a new array from an existing array... and that's exactly what it's doing in this case. It's instantiating and returning an entirely unnecessary array, populated with `undefined`. On top of that, you've polluted `Array.prototype` with another enumerable property. The array methods `map`, `forEach`, `filter`, `reduce`, `some`, etc are built with specific purposes in mind. While this may "function" it's ridiculously inefficient because it's doing unnecessary work... because you've selected the inappropriate method. – canon Jan 07 '16 at 14:56
  • 2
    Vote down means "wrong", this is not a wrong answer. If you don't like an answer, feel free to comment but if it's really bad it won't get enough vote ups. Vote down is a strong negative, that's why StackOverflow will give you negative points when you vote down, so please use them carefully. – Kamil Kiełczewski Sep 19 '19 at 07:09