Four ways to sum an array of numbers in JavaScript

Do you like numbers? Math?

Arrays and similar data types in other languages are a common way to store data. They are one of the basic data types to become familiar with, and knowing how to manipulate them is an important skill of a developer of any experience level.

For now, we will work with the following array, comprised solely of numbers.

let swan = [4, 8, 15, 16, 23, 42];

For loop

The for loop is the way many people will first learn how to traverse an array. It allows for more control over how the array will be traversed, though it is not as elegant or as pretty to look at as the other options.

If you console.log(sum) at each step, you can see sum at each step.

function sumArrFor(arr) {
    let sum = 0;
    for (let i = 0; i <= arr.length - 1; i++) {
        sum += arr[i];
        console.log(sum); // See 'sum' at each step
    }
    return sum;
}

sumArrFor(swan); // [4, 8, 15, 16, 23, 42] => 108

The .forEach() array method

The .forEach() array method is a slightly unusual way to sum an array of numbers. It is similar to the for loop in its appearance, though control over the traversal of the array is different than the relative familiarity of the same in the for loop.

Like the for loop, if you console.log(sum) at each step, you can see sum at each step.

function sumArrForEach(arr) {
    let sum = 0;
    arr.forEach(item => {
        sum += item;
        console.log(sum); // See 'sum' at each step
    });
    return sum;
}

sumArrForEach(swan); // [4, 8, 15, 16, 23, 42] => 108

The .reduce() array method

The .reduce() array method is arguably the most elegant, at least in the sense that it can be reduced (pun intended) to a single line. Single line however is not as readable as multiple lines. In all fairness, "elegant" is probably subjective, though you might see single line .reduce() in the wild, or on sites like Codewars.

In any case, if you use .reduce(), you should specify an initialValue. The initialValue is effectively sum from the for loop option and the .forEach() option.

To see the sum at each step, you can console.log(acc), but only when you don't use single line .reduce().

Per MDN, initialValue is optional, though to protect yourself against some edge cases, best practice is to include the initialValue. The initialValue when summing is generally 0.

// Multi-line
function sumArrReduce(arr) {
    const sum = arr.reduce((acc, n) => {       
        console.log(acc); // See 'acc' at each step
        return acc + n;
    }, 0); // 0 is the inital value
    return sum;
}

// Single line
const sumArrReduce2 = arr => arr.reduce((acc, n) => acc + n, 0);

sumArrReduce(swan) // [4, 8, 15, 16, 23, 42] => 108
sumArrReduce2(swan) // [4, 8, 15, 16, 23, 42] => 108

For...of loop

Last but not least is for...of. I like to think of it as an odd amalgamation of (1) .forEach(), and (2) the "regular" for loop. for...of is not to be confused with for...in.

Relative to the other options, I believe for...of provides the least amount of control over the traversal of the subject array.

function sumArrForOf(arr) {
    let sum = 0;
    for (const item of arr) {
        sum += item;
        console.log(sum); // See 'sum' at each step
    } 
    return sum;
}

sumArrForOf(swan) // [4, 8, 15, 16, 23, 42] => 108

A note on Big O Notation

At the scale of the silly swan array, a discussion on Big O Notation is not really necessary.

However, if your array is large enough, there might be differences in the efficiency in each of the above options.