Sam Johnston - Senior Software Engineer

Sam Johnston

Senior Software Engineer
AWS, NodeJS, React

Thursday, 20 August 2020

Home » Articles » Array.reduce() Learnings

Array.reduce() Learnings

Array.reduce() Learnings

A deep dive into the reduce() array method.

On the surface, its relatively straightforward, reduce() accepts two arguments:

  1. A callback function which itself has two main arguments, the accumulator and the current value.
  2. An optional initial value.

Most example code has you adding numbers together like this

const array = [1, 2, 3, 4, 5];
array.reduce((accumulator, currentValue) => {
  return accumulator + currentValue; // Returns 15
}, 0);

Or concatenating strings, like this:

const array = [1, 2, 3, 4, 5];
array.reduce((accumulator, currentValue) => {
  const string = currentValue.toString();
  return accumulator + string; // Returns 12345
}, '');

But neither of these examples are particularly practical, I found them to be too simplistic and both could instead just use map(), or forEach().

Reduce really shines when its used as part of a more complex function, a recursive function or as a means of mapping data

// Convert Deep Object to Flat Array
const objectToFlatArray = (obj, keyPrefix = '', clean = false) =>
  Object.keys(obj).reduce((acc, key) => {
    // This will upcase and remove invalid characters
    const cleanKey = clean ? key.replace(/[:]/g, '').toUpperCase() : key;
    const concatKey = `${keyPrefix}${cleanKey}_`;

    if (obj[key] && typeof obj[key] === 'object') {
      return [...acc, ...objectToFlatArray(obj[key], concatKey)];
    }

    return [...acc, [keyPrefix + cleanKey, obj[key]]];
  }, []);

// Flatten a Deep Object
const flattenObject = (obj, keyPrefix = '') =>
  Object.keys(obj).reduce((acc, key) => {
    const cleanKey = key.replace(/[:]/g, '').toUpperCase();
    const concatKey = `${keyPrefix}${cleanKey}_`;

    if (obj[key] && typeof obj[key] === 'object') {
      return { ...acc, ...flattenObject(obj[key], concatKey) };
    }

    return { ...acc, ...{ [keyPrefix + cleanKey]: obj[key] } };
  }, {});