Reducing~ Basics ~

Reducing

Very often, we have to transform objects from one shape to another. My favorite tool for such transformations is the reduce function. Let's say that we have the following array of objects:

const positions = [
  { languages: ["HTML", "JavaScript", "PHP"], years: 4 },
  { languages: ["JavaScript", "PHP"], years: 2 },
  { languages: ["C", "PHP"], years: 3 },
];

And we need the total number of years for each of the languages. The solution involves looping over the items and some value aggregation. Precisely what reduce is made for:

const yearsOfWriting = positions.reduce((res, { languages, years }) => {
  languages.forEach((lang) => {
    if (!res[lang]) res[lang] = 0;
    res[lang] += years;
  });
  return res;
}, {});

console.log(yearsOfWriting); // { HTML: 4, JavaScript: 6, PHP: 9, C: 3 }

reduce is a method of the Array prototype. It allows us to accumulate a value by looping over the array's items.

It is possible to use the function on objects too. Not directly, but we can pass the object to Object.keys. We will get back an array of all the properties, and we can iterate over them. Let's continue the example and ask another question - how many years in total?

const yearsOfWriting = { HTML: 4, JavaScript: 6, PHP: 9, C: 3 };
const totalYears = Object.keys(yearsOfWriting).reduce((total, key) => {
  return total + yearsOfWriting[key];
}, 0);

console.log(totalYears); // 22