ChatGPT解决这个技术问题 Extra ChatGPT

How to find the sum of an array of numbers

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.

@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.)
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".
No built in reducer one could feed to Array.reduce? Thinking something like [1,2,3].reduce(Math.sum).

R
Ry-

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? :-)


Assuming we all use ES2015, we can make it less verbose : [1, 2, 3].reduce((a,b)=>a+b)
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])?
it's lovely : )
Shame that the Array prototype doesn't support sum(). Using reduce() obfuscates the intent.
S
Stan Kurdziel

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.


You do know that this magic with reduce() is still 25-30% slower than a simple indexed for() loop after long years? jsperf.com/reduce-vs-loop/4
P
Peter Mortensen

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);

IE8 doesn't support it, and it doesn't look like jQuery intends on adding it. However, Prototype has it.
@Ishmael, you can use UnderscoreJS, which falls back to the browser's implementation if available, or implements its own otherwise.
What's counter-intuitive about reduce()?
@s4nji Array.prototype.reduce() reduces an array to a single return value.
@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. :-)
K
Kartikey
var arr = [1, 2, 3, 4];
var total = 0;
for (var i in arr) {
  total += arr[i];
}

This is way faster than the jQuery.each() solution above.
@Sprog: However, using (var i=0; i<arr.length; i++) is even faster. And even then, using var sum=0; var i=arr.length; while(i--) sum += arr[i] is even faster still.
Using for... in loops on arrays works in this case _ coincidentally_ and because arrays extend objects. Riking's solution is better
@BenjaminGruenbaum provided that nothing has added enumerable properties to array's prototype...
@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.)
T
Tyler Carter
var total = 0;
$.each(arr,function() {
    total += this;
});

Please, please, please use the answer with reduce below; do not declare mutable vars when you do not have too.
This answer is under meta discussion
Please do not use this, even though it is the "accepted answer"; the answer by Florian below is much better!
@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.
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.
g
geek-merlin

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.


s
simhumileco

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

array = [1, 2, 3, 4];
sum = _.sum(array); // sum == 10

Work well with Typescript too.
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".
and if you dont happen to be using lodash, you can npm it.. no offenece to the dramaqueen @Blaze612YT
@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.
y
yckart

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;
}

While clever, I'd find code declaring sum outside the loop much more readable.
@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... ;)
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;
P
Peter Mortensen
arr.reduce(function (a, b) {
    return a + b;
});

Reference: Array.prototype.reduce()


This will fail if arr is [].
Add a default value, like so: arr.reduce(function (a, b) { return a + b; }, 0);
A
Alireza

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...


R
Rohit Bhalke

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


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.
e
electron

Funny approach:

eval([1,2,3].join("+"))

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.
@user40521 has already answered this the way i think. I didn't see it.
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.
Errm, [1,"2;YourProgram.ripToShreds();3",4]
So I'm getting NaN when trying eval(['alert("removing your computer")',2,3].join("+")) wrong answer 0/10
S
Simon Baumgardt-Wellander

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.


Also, any C or Java programmer would be able to understand this.
for the simple purpose of summing up all values the simple plain old for loop has no rivals in terms of execution time
Only problem is, it's a bit annoying when you have 20 for loops all nested in each other
C
Community

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.


How is this any different from this 2012 answer or this 2014 answer? There's two solutions you haven't seen.
M
Md.Shakil Shaikh

You can try the following code:

[1, 2, 3, 4].reduce((pre,curr)=>pre+curr,0)

H
Hunter

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

u
user40521
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.


I'm half laughing
eval(['alert("removing your computer")',2,3].join("+"))
G
Guy

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.


If you're going to mess with prototypes (and you shouldn't), a Math.prototype.sum method would be more appropriate.
c
caiohamamura

ES6 for..of

let total = 0;

for (let value of [1, 2, 3, 4]) {
    total += value; 
}

P
Peter Mortensen

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)

P
Paul Roub

Use reduce

let arr = [1, 2, 3, 4]; let sum = arr.reduce((v, i) => (v + i)); console.log(sum);


Y
Yas

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

R
Rex Low

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.


elegant? more like way too complicated
up for recursive way
K
Kamil Kiełczewski

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


S
Santosh

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


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)
a
antonjs

You can combine reduce() method with lambda expression:

[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);

A
Ahmad Moghazi

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

A
Adrian Swifter

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)

b
bahri noredine

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);

S
Shoaib Khalil

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)