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,
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];
This will take on average 1.57 ms/run (measured over 1000 runs on an array of 100 random normal numbers), compared to 3.604 ms/run with the eval()
method above and 2.151 ms/run with a standard for(i,length,++) loop.
Methodology note: this test was run on a Google Apps Script server, so their javascript engines are pretty much the same as Chrome.
EDIT: --i
instead of i--
saves 0.12 ms each run (i-- is 1.7)
EDIT: Holy expletive, never mind this whole post. Use the reduce() method mentioned above, it's only 1 ms/run.
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)
)
You get a TypeError
console.log(
[].reduce((a, b) => a + b)
)
console.log(
[1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)
console.log(
[].reduce(function(acc, val) { return acc + val; }, 0)
)
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))
)
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.
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;
}
In Lisp, this'd be exactly the job for reduce
. You'd see this kind of code:
(reduce #'+ '(1 2 3)) ; 6
Fortunately, in JavaScript, we also have reduce! Unfortunately, +
is an operator, not a function. But we can make it pretty! Here, look:
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? :-)
Even better! If you're using ECMAScript 2015 (aka ECMAScript 6), it can be this pretty:
const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a,0);
console.log(sum); // 6
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
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.