avatarNicky Christensen

Summary

The provided web content offers an in-depth exploration of the JavaScript array.reduce() method, showcasing its versatility through various practical examples.

Abstract

The article "A closer look on array.reduce() with useful examples" delves into the JavaScript array.reduce() method, which is often underutilized due to its perceived complexity. The author explains that reduce() is a powerful tool for transforming arrays into a single value, whether it be a number, object, or a new array. The method is demonstrated to be more efficient than traditional loops for tasks such as summing array elements, flattening nested arrays, and filtering objects based on certain properties. Through examples like calculating the total price of items in a shopping basket, merging multiple arrays into one, and extracting specific properties from an array of objects, the author illustrates how reduce() can lead to cleaner and more maintainable code. The article also provides tips on best practices, such as the importance of an initial value for the accumulator and the necessity of returning the accumulator after each iteration.

Opinions

  • The author initially found array.reduce() challenging to understand but came to appreciate its power and flexibility beyond simple summations.
  • The article suggests that reduce() is a superior alternative to traditional loops (for, .map, .forEach, .filter) for certain use cases, particularly when transforming arrays.
  • The author emphasizes that reduce() can greatly simplify code and improve readability when used appropriately.
  • It is the author's opinion that developers should actively replace some of their for loops with reduce() to experience its benefits and to get more acquainted with the method.
  • The author encourages readers to follow them on social media and visit their portfolio website for further engagement and learning opportunities.

A closer look on array.reduce() with useful examples

For a long time I had a hard time wrapping my head around array.reduce(). All examples I stubled upon were basic examples of getting the sum of an array of numbers, which I didn’t find myself needing that often, but what I didn’t understand was the reduce was so much more than this.

arrays.reduce() runs a callback function, just like .map .forEach .filter, but reduce also takes a parameter called initial value that gets passed to the callback function, also often to referred as the accumulator in reduce. The reason for this is reduce modifies your array, and returns only a single value, which basically means that for each element in the array it will run a function, and in the end return a single value based on your array.

Sum it up

As mentioned earlier, the use cases I saw when learning reduce was returning a sum of an array of numbers, and this is a great use case for reduce. Imagine you are working on an eCommerce project where you have products that can be added to a basket and you need to show the total sum of all product in the basket. You could solve this with a forLoop, but using reduce makes it so much easier

const basketItems = [
 {
    productName: 'Lenovo Carbon',
    price: 2145
  },
  {
    productName: 'Macbook Pro',
    price: 3111
  },
  {
    productName: 'Google Home',
    price: 250
  }
]
let basketSum = basketItems.reduce((acc, basketItem) => {
 return acc + basketItem.price
}, 0); // Take notice of last argument is a number
console.log("sum in basket", basketSum); // Returns 5506

Flatten arrays of arrays

In some cases, I’ve found myself having two arrays I needed merged into one single array.

//Flatten
const multipleArrays = [["Leonardo", "Rafael", "Donatello"], ["Michaelangelo", "April", "Splinter"], ["Shredder", "B-Bob", "Rock Steady"]];
const flat = multipleArrays.reduce((acc, item) => {
  return acc.concat(item);
}, []); // Returns ["Leonardo", "Rafael", "Donatello", "Michaelangelo", "April", "Splinter", "Shredder", "B-Bob", "Rock Steady"]

Multiple arrays from objects into a single array

You might have an array of objects where each object can hold an array on some values, and you want to pull out all these values into a single array.

let data = [
 {
  persons: ["Michaelangelo", "Leonardo", "Donatello", "Rafael"],
  enemies: ["Shredder", "Beebob", "Rocksteady"]
 },
 {
  persons: ["Luke Skywalker"],
  enemies: ["Darth Vader"]
 }
]
const flat = data.reduce((acc, item) => {
 item.persons.forEach(person => acc.push(person));
  item.enemies.forEach(person => acc.push(person));
  return acc
}, []); // Returns ["Michaelangelo", "Leonardo", "Donatello", "Rafael", "Shredder", "Beebob", "Rocksteady", "Luke Skywalker", "Darth Vader"]

We are looping over both arrays in each object and pushing it into our accumulator. Our end result will now hold an array of all persons and enemies in one single array

Ok, the first two examples are very basic usages of reduce, so let’s try looking at some more complex use cases. In the three next examples we’ll be working with this dataset:

const people = [
 {
   name: 'Leo',
    age: 22,
    blackBelt: true,
    experience: 18,
    availableForWork: true,
    isTurtle: true,
    friends: [
     {
       name: 'Micky',
        age: 44,
        blackBelt: false,
        availableForWork: true,
        isTurtle: false
      },
      {
       name: 'Donny',
        age: 32,
        blackBelt: true,
        availableForWork: false,
        isTurtle: false
      }
    ]
  },
  {
   name: 'Rafael',
    age: 21,
    blackBelt: true,
    experience: 12,
    availableForWork: true,
    isTurtle: true,
    friends: [
     {
       name: 'Leo',
        age: 31,
        blackBelt: false,
        isTurtle: false,
        availableForWork: false
      },
      {
       name: 'Donny',
        age: 33,
        blackBelt: true,
        isTurtle: false,
        availableForWork: true
      }
    ]
  },
  {
   name: 'Donatello',
    age: 19,
    blackBelt: true,
    experience: 16,
    availableForWork: false,
    isTurtle: true,
    friends: [
     {
       name: 'Nicky',
        age: 34,
        blackBelt: false,
        isTurtle: false,
        availableForWork: true
      },
      {
       name: 'Splinter',
        age: 73,
        blackBelt: true,
        isTurtle: false,
        availableForWork: false
      }
    ]
  },
  {
   name: 'Michaelangelo',
    age: 17,
    blackBelt: true,
    experience: 10,
    availableForWork: false,
    isTurtle: true,
    friends: [
     {
       name: 'April',
        age: 21,
        blackBelt: false,
        isTurtle: false,
        availableForWork: false
      },
      {
       name: 'B-Bob',
        age: 21,
        blackBelt: true,
        isTurtle: false,
        availableForWork: true
      }
    ]
  }
];

Create a single array from object properties

In this example I have an array of people, each person also has some friends, which holds an array of friends. Now I want to pull out the ages of all persons and friends and have that in a single array.

const agesOfAllPersons = people.reduce((acc, currentValue) => {
 acc.push(currentValue.age)
  currentValue.friends.forEach( friend => {
      acc.push(friend.age);
  })
  return acc;
}, []); // Returns [22, 44, 32, 21, 31, 33, 19, 34, 73, 17, 21, 21]

Sum it up some more

Let’s say I want to sum up the ages for all persons and their friends. We’ll use the array from before, and try to some all ages together into one single number:

const sumOfAllAges = people.reduce((acc, currentValue) => {
   //let age = acc + currentValue.age;
    acc = acc + currentValue.age;
    let friendsAge = currentValue.friends.forEach((friend) => {
     acc += friend.age
    });
    return acc
}, 0); //Returns 368

Create unique array from object property

In some cases, you might want to have a unique array based of some conditions to be true or false. In this example we are filtering out all people in our array that isn’t available for work, and thereby creating a unique array with the people who are available for work

const availableForWork = people.reduce((acc, currentValue) => {
 if(currentValue.availableForWork === true) {
   acc.push(currentValue);
  }
  currentValue.friends.forEach(friend => {
    if(friend.availableForWork === true) {
      acc.push(friend);
    }
  });
  return acc;
}, []); // Returns an array of 6 people that are available for work

Create own structure from array

Sometimes the data you get from a certain API may not always be the way you want it to be, which can lead to frustrations. In this example we have an array of persons objects, and you need to find the person with ID 2. With the data below you could just iterate over the items and filter out the person with ID 2. But by creating you own structure you can avoid this.

const idToSelect = 2;
const peopleArray = [
  {
    id: 1,
    name: 'Rafael'
  },
  {
    id: 2,
    name: 'Leonardo'
  },
  {
    id: 3,
    name: 'Michaelangelo'
  },
  {
    id: 4,
    name: 'Donatello'
  },
];
const mapPeople = peopleArray.reduce((map, person) => {
  map[person.id] = person
  return map;
}, {});
const selectedPerson = mapPeople[idToSelect]; // Returns the person with the id of 2

Sidenote:

  • If you don’t pass an initial value, reduce will take the first item in your array as the initial value
  • Always remember to return the accumulator. For reduce to work you must always return a value.
  • Reduce can transform any array into a single value
  • Is most use cases you would use reduce to transform arrays into either a number, object or a new array

Reduce can do a lot more than these examples, but I hope you can see the power of reduce and how you can use it to create simpler and cleaner code.

I urge you to try it out!

For really getting to know reduce I recommend you trying to replace some of your for loops with reduce, where it seems to fit.

Thanks for reading and I hope you liked the article

If you’d like to catch up with me sometime, follow me on Twitter | LinkedIn| Facebook or simply visit my portfolio website (That is however in Danish)

JavaScript
Functional Programming
Arrays
Front End Development
ES6
Recommended from ReadMedium