Sum numbers in an array with JavaScript
There are several ways to compute the sum of numbers in an array with JavaScript. The approaches differ mainly in how readable they are — and readable code is easier to maintain and easier for others to understand and build on.
TL;DR
- There are many ways to sum numbers in an array, but several of them are hard to read and unnecessarily complicated.
- The best way is using the built-in
reducefunction — or the newerMath.sumPreciseif you can rely on it being available.
Summing numbers in an array
In the upcoming examples, I'll start from this array of random numbers:
const numbers = [20, 38, 23, 1, 39, 71]
Option 1: manual summation (a terrible option)
You can do the summation using only addition, like this:
const sum =
numbers[0] + numbers[1] + numbers[2] + numbers[3] + numbers[4] + numbers[5]
// sum = 192
This option is terrible because it requires knowing how many numbers are in the array. If a number is added to the array, the sum would be wrong.
Option 2: for-loop (a bad option)
Historically, summations in JavaScript have been done with a for-loop:
let sum = 0
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i]
}
// sum = 192
It's still a clunky way to sum. The style is imperative — you have to manage how the loop runs yourself — and it requires an index variable like i whose only job is to track position. Such variables can and usually should be avoided.
Option 3: forEach-loop (an OK option)
Using forEach reads more naturally than a for-loop, but it still requires declaring let sum = 0 and mutating that variable on every iteration:
let sum = 0
numbers.forEach((number) => (sum += number))
// sum = 192
forEach is a higher-order function that runs a callback for each element in the array. It removes the index variable but not the mutation.
Option 4: reduce (the best option)
Even nicer is the built-in reduce function:
const sum = numbers.reduce((acc, number) => acc + number, 0)
// sum = 192
reduce takes a function with parameters acc and number, representing the accumulated value and the current value in the numbers array. Right of the arrow defines what to do with the values. In the first iteration, acc is 0 (the initial value defined as the second argument) and number is 20. Then the result of acc + number is saved to acc in the next iteration.
Summing numbers in more complex arrays
In many cases the arrays you want to sum are more complex than the previous example. Let's start from this array containing information about all rooms in an apartment:
const rooms = [
{ name: "Living room", isRenovated: true, area: 31 },
{ name: "Kitchen", isRenovated: false, area: 15 },
{ name: "Bedroom", isRenovated: false, area: 21 },
{ name: "Bathroom", isRenovated: true, area: 13 },
{ name: "Hall", isRenovated: false, area: 9 },
]
Let's say we want to compute the total area of the apartment.
Option 1: reshape the array, then sum
Use map to turn each room into just its area, then sum the resulting array of numbers.
const totalArea = rooms
.map((room) => room.area)
.reduce((acc, area) => acc + area, 0)
// totalArea = 89
Option 2: extract the area directly during summation
With the second strategy, reduce is used to extract the area from the objects directly:
const totalArea = rooms.reduce((acc, room) => acc + room.area, 0)
// totalArea = 89
Of these, I think option 2 is the nicest because it's both the most compact and the most readable.
Summing with filtering
To make it a bit more complicated, we might want to know the total area of the rooms that haven't been renovated.
Option 1: filter, map, sum
Use filter to keep only the rooms that haven't been renovated, then reshape and sum as before.
const totalAreaOfNotRenovatedRooms = rooms
.filter((room) => !room.isRenovated)
.map((room) => room.area)
.reduce((acc, area) => acc + area, 0)
// totalAreaOfNotRenovatedRooms = 45
Option 2: filter, extract area directly during summation
Skip the intermediate map and pull the area out inside reduce itself.
const totalAreaOfNotRenovatedRooms = rooms
.filter((room) => !room.isRenovated)
.reduce((acc, room) => acc + room.area, 0)
// totalAreaOfNotRenovatedRooms = 45
Option 3: filter with if-statement inside reduce
Drop the separate filter call and branch inside the reducer with an if-statement to decide whether to add a room's area.
const totalAreaOfNotRenovatedRooms = rooms.reduce((acc, room) => {
if (!room.isRenovated) return acc + room.area
return acc
}, 0)
// totalAreaOfNotRenovatedRooms = 45
Option 4: filter with ternary operator in reduce
The same branching can be expressed more compactly with a ternary operator.
const totalAreaOfNotRenovatedRooms = rooms.reduce(
(acc, room) => (room.isRenovated ? acc : acc + room.area),
0,
)
// totalAreaOfNotRenovatedRooms = 45
I think option 2 is the best in this case. You can almost read the code as plain text and understand what's happening:
First filter out the rooms that aren't renovated, then sum the area of each room.
Better alternatives
JavaScript now has a built-in static method for exactly this: Math.sumPrecise. It takes an iterable of numbers and returns the sum without floating-point precision issues:
const sum = Math.sumPrecise([20, 38, 23, 1, 39, 71])
// sum = 192
For the apartment example, combine it with map:
const totalArea = Math.sumPrecise(rooms.map((room) => room.area))
// totalArea = 89
Math.sumPrecise is a recent addition, so support still varies across environments — check Can I use for the current status. Where it isn't available, reduce is still a great choice.
There you go — now you know everything about summing numbers in an array with JavaScript!
References
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sumPrecise
- https://github.com/tc39/proposal-math-sum
