DEV Community

Cover image for Code Snippets: Array.prototype.reduce()
Ethan Smith
Ethan Smith

Posted on

Code Snippets: Array.prototype.reduce()

What is Array.prototype.reduce()?

The reduce method runs a callback function on each item of an array, passing in the value that was returned by the previous.

The previous value on the first call will be the item at index 0, unless otherwise provided in the method call.

Syntax

Array.prototype.reduce((prev, curr) => newValue)
// or
Array.prototype.reduce((prev, curr) => newValue, initialValue)
Enter fullscreen mode Exit fullscreen mode

Examples

Get Sum of Numbers

Here we add the current item to the value returned by the last.

const numbers = [1, 2, 3, 4, 5];

const sum = numbers.reduce((acc, curr) => acc + curr); 
// 15
Enter fullscreen mode Exit fullscreen mode

Get Max of Numbers

Instead of returning the previous value added to the current value like we did with the sum example, we simply return the larger of the two.

const numbers = [1, 2, 3, 4, 5];

const max = numbers.reduce((acc, curr) => (acc > curr ? acc : curr)); 
// 5
Enter fullscreen mode Exit fullscreen mode

This can be applied to an array of objects too.

const people = [
    { name: "John", age: 20 },
    { name: "Jane", age: 21 },
    { name: "Joe", age: 22 },
    { name: "Jack", age: 23 },
    { name: "Jill", age: 24 },
    { name: "Juan", age: 25 },
];

const oldestPerson = people.reduce((oldest, current) =>
    current.age > oldest.age ? current : oldest
);
// { name: "Juan", age: 25 }
Enter fullscreen mode Exit fullscreen mode

Combine Filter and Map

Sometimes we need to filter data, and then map that data to a new shape or type. However, we can do both of those things with reduce.

In doing so, we avoid the need to traverse the array twice.

const people = [
    {
        firstName: "John",
        lastName: "Doe",
        age: 20,
    },
    {
        firstName: "Jane",
        lastName: "Doe",
        age: 21,
    },
    {
        firstName: "Joe",
        lastName: "Doe",
        age: 22,
    },
    {
        firstName: "Jack",
        lastName: "Doe",
        age: 23,
    },
    {
        firstName: "Jill",
        lastName: "Doe",
        age: 24,
    },
    {
        firstName: "Juan",
        lastName: "Doe",
        age: 25,
    },
];


const canDrink = people.reduce(
    (drinkers, curr) =>
        curr.age >= 21
            ? [...drinkers, `${curr.firstName} ${curr.lastName}`]
            : drinkers,
    []
);
// [ "Jane Doe", "Joe Doe", "Jack Doe", "Jill Doe", "Juan Doe" ]
Enter fullscreen mode Exit fullscreen mode

We did pass an initial value this time because we are creating an array, if we did not pass [] then the function would try and call .push on a person object which would cause an uncaught TypeError.

We can also accomplish this without copying the drinkers array each time.

const canDrink = people.reduce((drinkers, curr) => {
    if (curr.age >= 21) {
        drinkers.push(`${curr.firstName} ${curr.lastName}`);
    }
    return drinkers;
}, []);
Enter fullscreen mode Exit fullscreen mode

In comparison, this would be the same effect with map and filter:

const canDrink = people
    .filter((person) => person.age >= 21)
    ?.map((person) => `${person.firstName} ${person.lastName}`);
Enter fullscreen mode Exit fullscreen mode

Convert Array to Object

We can easily convert an array to an object, in this case a dictionary of week days and their respective number value.

For this specific example we will accept an optional 3rd parameter for the index in our callback function.

const days = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
];

const daysOfWeek = days.reduce((newDays, day, index) => {
    newDays[day] = index;
    return newDays;
}, {});
// { Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6 }
Enter fullscreen mode Exit fullscreen mode

Change Object Shape

We can also change the shape of an object to fit our needs.

const coordinates = {
    lat1: 0,
    lon1: 0,
    lat2: 31.968599,
    lon2: -99.9018131,
    lat3: 26.820553,
    lon3: -80.053407,
    lat4: 25.774252,
    lon4: -80.193665,
};

const parsedCoordinates = Object.keys(coordinates).reduce(
    (acc, key) => {
        const value = coordinates[key];
        if (key?.includes("lat")) {
            acc["lat"].push(value);
        } else {
            acc["lon"].push(value);
        }
        return acc;
    },
    { lat: [], lon: [] }
);
/**
{
  lat: [ 0, 31.968599, 26.820553, 25.774252 ],
  lon: [ 0, -99.9018131, -80.053407, -80.193665 ]
}
*/`
Enter fullscreen mode Exit fullscreen mode

Conclusion

Overall the reduce method can make your work a lot easier if you know how to use it!

Top comments (2)

Collapse
 
konrud profile image
Konstantin Rouda

I believe for finding Max Number example
it might be easier, and perhaps more readable, to use Math.max()


const numbers = [1, 2, 3, 4, 5];

const max = Math.max(...[1, 2, 3, 4, 5]); 
// 5

Enter fullscreen mode Exit fullscreen mode
Collapse
 
esdev profile image
Ethan Smith

Absolutely, the max numbers example in this article is only to show basic usage and syntax of the reduce method with a very simple use case. Using Math.max would likely be a better option for finding the maximum in most real programming scenarios.