Explain Codes LogoExplain Codes Logo

How to call reduce on an array of objects to sum their properties?

javascript
reduce
array
functions
Alex KataevbyAlex Kataev·Nov 18, 2024
TLDR

To sum the values of a specific property from an array of objects, utilize the .reduce() function, providing an initial value:

const array = [{ score: 10 }, { score: 20 }, { score: 30 }]; const totalScore = array.reduce((accumulator, currentValue) => accumulator + currentValue.score, 0); console.log(totalScore); // Concatenation of numbers, otherwise known as "sum" output: 60

Note: Make sure the property name (score) matches the keys in your objects.

Prepping for the big reduce

Before utilizing .reduce(), it is critical to supply an initial value. This small step enables handling of empty arrays and undefined properties, effectively side-stepping errors such as NaN. What's more, if you're a TypeScript enthusiast, this initial value ensures type inference for the accumulator.

Making magic with destructuring

When using .reduce(), you have the power to destructure the current object for a easier access to specific properties:

const totalScore = array.reduce((accumulator, { score }) => accumulator + score, 0);

Embrace destructuring to tell your code's story better.

Quick draw with ES6 arrow Functions

The ES6 arrow function offers a cleaner syntax for .reduce(), that's faster than the Millennium Falcon :

const totalScore = array.reduce((accumulator, obj) => accumulator + obj.score, 0);

Mutate not with initial values

Immutability is core to functional programming. Avoid mutations by providing an initial value to .reduce().

Handling the layers: Nested structures

When confronted with arrays of arrays or objects with nested arrays, flatten the array before using .reduce() :

const arrayOfArrays = [[1, 2], [3, 4], [5, 6]]; const flatArray = arrayOfArrays.flat(); // Flatten it like a pancake const sum = flatArray.reduce((accumulator, num) => accumulator + num, 0); // Then, it's reducing time!

Superpowers with Map-Reduce

When the property to be summed is buried deeper or needs transformation before reduction, come to the rescue with .map() chained with .reduce() :

const totalScore = array .map(item => item.score * 2) // Double trouble! .reduce((accumulator, score) => accumulator + score, 0); // and.. tadah! reduction.

Trying-on practical tips

Guardians of property-existence

Before marching onto property summing, verify if the property even exists. This can be our guard clause against pesky runtime errors:

const safeSum = array.reduce((accumulator, obj) => 'score' in obj ? accumulator + obj.score : accumulator, 0); // Score property, you shall not pass (if you don't exist)!

Wrestling with mixed data types

When your array is a cocktail of types, you must sanitize your data or affirm conditions in your reducing function to make sure the sum is not wonky:

const mixedArray = [{ score: 10 }, { score: '20' }, { }]; const numericSum = mixedArray.reduce((accumulator, obj) => { const score = parseInt(obj.score, 10); // Score comes out clean after a parseInt shower return Number.isNaN(score) ? accumulator : accumulator + score; // No dirty data shall pass! }, 0);

Transducers for performance

Enjoy the thrill of transducers for complex transformations. These combine transformations and reduce them to a performant single operation:

// Transducer to double the score and then sum const doubleSumTransducer = array.reduce((accumulator, obj) => accumulator + (obj.score * 2), 0); // And reduce shrank to a transducer!

Wielding the practical power of reduce

Parameters - More the merrier

.reduce() function actually accepts four parameters: accumulator, current item, item index, and the entire array. These optional parameters open a world of more complex scenarios:

const detailedSum = array.reduce((accumulator, obj, index, array) => { // Your complex logic here return accumulator + obj.score; // Back to basics }, 0);

The power beyond numbers

.reduce() is a versatile tool, enabling reduction of an array to any value type: strings, objects, or even functions:

const concatenatedNames = userList.reduce((names, user) => names + user.name + ' ', ''); // Concatenating names like a game of Worms.

Advanced - Custom flattening

If you encounter labyrinth-like nested arrays or complex JSON structures, draw upon a specialized flattening function with .reduce():

function customFlatten(arr) { return arr.reduce((flat, toFlatten) => { // It's dangerous to go alone. Take this, a custom flattening function! return flat.concat(Array.isArray(toFlatten) ? customFlatten(toFlatten) : toFlatten); }, []); }