# Reduce method in practice - Part 1

JavaScript has a cool method called reduce. Unfortunately, understanding how reduce works and when to use it can be hard at times. So first I’ll start out with the compulsory basic examples, and then I’ll show you some more complex use cases.

## What is reduce method?

`reduce` is a native array method in JavaScript, so, no surprise, we can apply it on arrays. The method accepts a callback function and an optional initial value as parameter.

The method will iterate over each element of the array and will apply the callback function on them, one by one. The function can have a four arguments but in real world apps we usually use less.

`reduce` as its name suggests reduces the number of elements in the array to a single value. Hence the general use case of this method is when we need to return the sum or a sort of summary of the elements, or there is a need to make one collection from many other. It’s worth considering `reduce` when one stumbles upon situations like these.

Now that we have the big picture on the method itself, let’s have a look at some basic examples.

## Calculating the sum of elements

Yes, this is the base case, it’s a must-have in an article about `reduce`. We have an array of numbers and want to calculate the sum of these numbers. What’s happening here? We want to reduce the number of elements in the array to one value, which will happen to be the sum of the values:

``````const numbers = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

const sum1 = numbers.reduce((sum, value) => {
return sum + value;
}, 0); // 129
``````

We are adding the first 10 prime numbers here. (As you might remember from school, 1 is not a prime.) `reduce` is passed both parameters: an anonymous callback function and the initial value, which is 0 (as the sum of the numbers is 0 before we start adding them).

The callback function itself also has two arguments. The first is called the accumulator (named `sum` here), and its value equals the initial value we have given as the second argument to `reduce` (initialValue) before we start applying the function on each element (i.e. 0). The second argument of the callback function called value refers to the individual values of the array as the method iterates over the elements. (Just too many arguments and values here.)

We will return the `sum + value` inside the callback function. This is what we want to do on each element of the `numbers` array. We want to add the numbers together.

Great, let’s see what happens when we start applying the function on the elements of the array. The first element is 2, so `sum + value` (0 + 2) will be equal to 2. This result will be the new value of the `sum` and `value` is assigned the next element of the array, which is 3 in our case. The callback function is applied on this element as well, so this time `sum + value` (2 + 3) will be 5, and this is the new value of `sum`, then we move on to the next element (so `value` will be 5), and so on. After applying the function on each element in the same way, we will get 129, and we store this result in the `sum1` variable.

We can also enter a named function as the first argument to `reduce`. All we have to do is to define our function separately and add it to the method:

``````const addNumbers = (sum, value) => sum + value;
const sum2 = numbers.reduce(addNumbers, 0); // 129
``````

We don’t call `addNumbers` function inside `reduce`, as the method does it for us when it iterates over each element.

Can I enter a number other than 0 as initialValue?

Sure, thanks for asking. We had 0 as initialValue in the previous example because we were interested in the sum of the elements in the array. If we pass in, say 31, then the sum of the elements in the array will be added to 31:

``````const sum3 = numbers.reduce(addNumbers, 31); // 160
``````

Can I leave off initialValue?

Yes, in this case the first parameter of the callback function (we called it `sum`) will be equal to the first element of the array (2 in this case) and the second parameter of the callback function (`value`) will initially be the second element of the array (3).

``````const sum4 = numbers.reduce(addNumbers); // 129
``````

Although in this case the end result will be the same as before, it’s safer to provide an initial value as the second argument in the callback of the `reduce` method.

## A simple solution for calculating the sum of elements with Lodash

Lodash has a fairly straightforward method for this case:

``````const sum5 = _.sum(numbers); // 129
``````

That’s it.

Lodash also has the `_.reduce` method, which will be discussed in the next article.

## Add every second element in the array

If, for some reason, we need to add every second, third etc. element in the array, we can make use of the third (optional) parameter of the callback function, which is the index of the array element:

``````const sumOfEverySecondNumber = numbers.reduce((sum, value, index) => {
if (index % 2 === 1) return sum + value;
return sum;
}, 0); // 71
``````

Hold on, what’s going on here?

We need the sum of every second number in the `numbers` array, so we should want the sum of elements with indices 1, 3, 5 etc. When the index of the actual element is odd, we add it to our accumulator (`sum`). If we get to even-indexed elements, we don’t want to include them in the sum, so we are not doing anything with them. We need, however, return `sum`, this is how `reduce` knows that it can move on to the next element of the array and can apply the function on it. By simply returning `sum`, we don’t apply any operations on the even-indexed elements.

## Counting instances

Assume we have a string and need to know how many times each letter occurs in the string.

``````const toBeCounted = 'aaaabbccccccd';
``````

A typical high school maths problem is to find out the number of permutations of these letters. (That is, how many different ways we can order these letters. The trick is that we can’t distinguish between the same letters.)

We will tally up the various letters and store the result in an object:

``````const tallyLetters = (object, letter) => {
if (!object[letter]) object[letter] = 0;
object[letter]++;
return object;
};
const letters = toBeCounted
.split('')
.reduce(tallyLetters, {}); // { a: 4, b: 2, c: 6, d: 1 }
``````

Let’s have a look step by step what the heck is happening here. First, we need to create an array of letters, as `reduce` works on arrays, so we `split` the string.

I defined a named function called `tallyLetters`, which will be called on each element inside `reduce`. The arguments are called `object` (this is the accumulator, its initial value is the empty object, this is the so called target of our operations) and `letter`, which is again the actual element of the array. Let’s go over the code line by line!

First, we check if the property with the actual letter exists. If not, we set its value to zero. Then we increase the value of the property by 1. The property of the actual letter will definitely exist by that time. If this is the first occurrence, its value will be set to 1 in this step (that’s why we defined 0 for the value in the first line). If the letter has already occurred before (say, we are on the third a), the if statement will be ignored and the value will jump to the next positive integer. In the end, we return object. After `reduce` iterates through the letters, we will get an object with the tally numbers.

## Concatenating arrays

Let’s say that we have some friends who shared their favourite movies with us:

``````const friends = [
{
name: 'Jill',
movies: ['The Last Jedi', 'The Empire Strikes Back']
},
{
name: 'Jack',
movies: ['Grown ups']
},
{
name: 'Jim',
movies: ['The Bourne Identity', 'The Man from U.N.C.L.E.']
}
];
``````

We want to collect all movies in one array to have a list of movies we want to watch in the next few weeks, because we appreciate our friends’ opinions on movies. In order to do that, we can type something like this:

``````const getMovies1 = (movies, friend) => movies.concat(friend.movies);

const allMovies = friends.reduce(getMovies1, []); // ['The Last Jedi', 'The Empire Strikes Back', 'Grown ups', 'The Bourne Identity', 'The Man from U.N.C.L.E.']
``````

The principle is the same as before. We define an initial value, which is an empty array. We want to collect all movies in this array. This will be the initial value of `movies`, and then we concatenate this `movies` array with each array from our friends’ objects.

We can also use array spread syntax in our function:

``````const getMovies2 = (movies, friend) => [...movies, ...friend.movies];
``````

The end result will be the same.

## Conclusion

The `reduce` method is not the easiest array method to grasp. We use it when we want to have one value/object/array from the initial array of elements. The abovementioned examples are the basic building blocks of how to use reduce. More complex use cases will come in the next article.