How to Sum a Property in an Array of Objects in JavaScript
A very common data manipulation task is to calculate the sum of a specific property across an array of objects. For example, you might need to find the total sales from a list of transactions, the total hours worked from a list of timesheets, or the total salary from a list of employees.
This guide will demonstrate the modern and most idi-omatic method for this task using Array.prototype.reduce(). We will also cover a more traditional approach using Array.prototype.forEach() for comparison.
The Core Method (Recommended): Array.prototype.reduce()
The reduce() method is the perfect tool for this job. It is designed to iterate over an array and "reduce" it to a single value (in this case, a sum). It is a powerful and highly efficient functional programming primitive.
For example, you have an array of objects and you want to sum the values of the salary property.
// Problem: Calculate the total of all 'salary' values.
const employees = [
{ id: 1, name: 'Alice', salary: 100 },
{ id: 2, name: 'Bob', salary: 200 },
{ id: 3, name: 'Charlie', salary: 300 },
];
Solution:
const employees = [
{ id: 1, name: 'Alice', salary: 100 },
{ id: 2, name: 'Bob', salary: 200 },
{ id: 3, name: 'Charlie', salary: 300 },
];
const totalSalary = employees.reduce((accumulator, currentObject) => {
return accumulator + currentObject.salary;
}, 0); // The 0 is the initial value for the accumulator
console.log(totalSalary); // Output: 600
This is the most concise and idiomatic way to perform a sum in modern JavaScript.
An Alternative Method: Array.prototype.forEach()
For those less familiar with reduce(), a simple forEach() loop is more imperative but can be easier to read and understand.
Solution:
- Initialize a
sumvariable to0. - Iterate over the array with
forEach(). - On each iteration, add the value of the target property to the
sum.
const employees = [
{ id: 1, name: 'Alice', salary: 100 },
{ id: 2, name: 'Bob', salary: 200 },
{ id: 3, name: 'Charlie', salary: 300 },
];
let totalSalary = 0;
employees.forEach(employee => {
totalSalary += employee.salary;
});
console.log(totalSalary); // Output: 600
This method achieves the same result and is perfectly valid, though reduce() is generally considered more idiomatic for this specific task.
How the reduce() Method Works
The reduce() method can be intimidating at first, but its concept is simple. It executes a "reducer" function on each element of the array, resulting in a single output value.
array.reduce(callback, initialValue)
Let's break down the callback: (accumulator, currentObject) => { ... }
accumulator: This is the value that gets carried over through each iteration. In our example, it's the running total of the sum. Its initial value is the second argument passed toreduce()(in our case,0).currentObject: This is the current object from the array that is being processed in the iteration.
Here's how our example executes:
- Iteration 1:
accumulatoris0,currentObject.salaryis100. The function returns0 + 100 = 100. - Iteration 2:
accumulatoris now100,currentObject.salaryis200. The function returns100 + 200 = 300. - Iteration 3:
accumulatoris now300,currentObject.salaryis300. The function returns300 + 300 = 600. - The loop finishes, and
reduce()returns the finalaccumulatorvalue:600.
Creating a Reusable Summing Function
If you need to sum different properties in your application, you can create a generic, reusable function.
function sumProperty(array, property) {
return array.reduce((accumulator, object) => {
return accumulator + object[property];
}, 0);
}
// Example Usage:
const data = [
{ value: 10, cost: 5 },
{ value: 20, cost: 10 },
{ value: 30, cost: 15 },
];
const totalValue = sumProperty(data, 'value');
const totalCost = sumProperty(data, 'cost');
console.log(totalValue); // Output: 60
console.log(totalCost); // Output: 30
This function uses bracket notation (object[property]) to dynamically access the property based on the string passed to the function.
Conclusion
Calculating the sum of a property in an array of objects is a common task with a clear, preferred solution in modern JavaScript.
- The
Array.prototype.reduce()method is the recommended best practice. It is a powerful, concise, and highly efficient tool designed for exactly this kind of aggregation. - A
forEach()loop is a perfectly acceptable and often more readable alternative for developers who are less comfortable with functional programming concepts.
By mastering reduce(), you can write more expressive and functional code for a wide variety of data manipulation tasks.