Sometimes we need to achieve a simple task, such as getting the sum from an array of integers, and we come up with a super-complex solution:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

function sum(nums) {
  let result = 0;

  for (let i = 0; i < nums.length; i++) {
    result += nums[i];
  }

  return result;
}

console.log(sum(numbers)); // => 55

Well, that actually works, but I think that we can do better!
What about using reduce method?

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const sum = (nums) => nums.reduce((total, number) => total + number);

console.log(sum(numbers)); // => 55

Wow, what’s happening here? reduce method applies a function to an array of values, reducing it to a single output value.

How is it useful?

First of all, using reduce instead of loops makes your code simpler.
Let’s see another example, where we need to find the average value of an array of numbers:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

function average(nums) {
  let sum = 0;

  for (let i = 0; i < nums.length; i++) {
    sum += nums[i];
  }

  return sum / nums.length;
}

console.log(average(numbers)); // => 5.5

Pretty same code as before, we just divide our sum by the original array length.
Let’s try to implement this using reduce:

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

function average = (nums) => nums.reduce((acc, num, index, array) => {

  const accValue = acc + num;
  const length   = array.length;

  return index === length - 1
               ? accValue / length
               : accValue;

});

console.log(average(numbers)); // => 5.5

Wow! Such a great escalation! How can this code be less complex than the previous one? Let’s analyze it:

average is a constant which returns a function that accepts an array as parameter.
That function returns the reduced value of the array parameter.
Inside the reduce callback, we have access to the following values:

  • acc which stands for “accumulator”. It accumulates the callback’s return values.

  • num which is the current value being processed by our callback function.

  • index which is the index of num inside our original array.

  • array which is the original array itself.

As you can see, we added a 0 as a second argument in our reduce method. It is an optional value which act as a initial accumulator value. Without it, during the first iteration (where index is equal to 0), the acc value is undefined.

Other use cases

Let’s pretend we have to calculate the total income of a restourant, given an array of orders:

const orders = [
  {
    client_id: "XX-12384",
    total:     55.15
  },
  {
    client_id: "JK-93876",
    total:     48.50
  },
  {
    client_id: "LL-92817",
    total:     21.75
  }
]

const total = orders.reduce((acc, order) => acc + order.total, 0);

console.log(total); // => 125.4

That’s extremely easy to do with reduce!
And what if wee need to flat down a multi-dimensional array?

const myArray = [[5, 10], [5, 0], [20, 40]];
const res     = myArray.reduce((acc, arr) => acc.concat(arr), []);

console.log(res); // => [5, 10, 5, 0, 20, 40]

That’s so easy!

Function composition

Another great thing about reduce is that it can help a lot when composing functions.
If you’re familirar with Scala, ReasonML or Haskell, you’ll find it awesome:

const double  = (x) => x * 2;
const addOne  = (x) => x + 1;
const addDesc = (x) => `Value is ${x}`;

const compose = (...fun) => input => fun.reduce((acc, fn) => fn(acc), input);

const func1 = compose(double, addOne, addDesc);
const func2 = compose(double, addOne);
const func3 = compose(addOne, addDesc);

func1(10); // => "Value is 21"
func2(20); // => 41
func3(50); // => "Value is 51"

Isn’t that awesome? You can compose your pipeline just like using the incredible pipeline operator!

ReduceRight

reduceRight acts just like the reduce method, but iterates the array from right to left:

const arr = ['a', 'b', 'c', 'd'];

const left  = arr.reduce((acc, item) => acc + item);      // => "abcd"
const right = arr.reduceRight((acc, item) => acc + item); // => "dcba"

Sometimes it can be handy to reduce an array without previously reversing it!

Did you like this article? Consider becoming a Patron!

This article is CC0 1.0 (Public Domain) licensed.