Introduction to Array.Reduce()
Tags: javascript, reduce, functional, programming
Published: 2017-09-15 00:36:20

---
title: Introduction to Array.Reduce()
published: true
description: What is Array.reduce()? Its use cases and how it helps you to to solve common tasks in a functional, side-effect free way in practice. 
tags: Javascript, reduce, Functional, programming
cover_image: https://thepracticaldev.s3.amazonaws.com/i/l87thc62palqitx6fk82.jpeg
---
# The concept of "Reducing" data

**For this introduction I will use an imaginary music library (consisting of tracks and playlists) application for the context of examples. The underlying concepts also apply to any other kind of application.**

When operating on data, it is often necessary to have knowledge about the data in a more abstract form than just the plain elements. In our music library you might want to know how many different titles of a single artist exist, or how many artists are in your library. You might also need to know all tracks being used in one or more playlists. You also might want to display how much hours of music the library (or a playlist) contains.
These are all typical use cases for reduce. (in general all kinds of counting, filtering, grouping, categorizing, unifying, concatenating data can be solved by applying reduce.  You can even *abuse* reduce for mapping data.)

**Be aware:** Sorting data with reduce won't work out fine and is nowhere near the *makes-sense* horizon.

# How `reduce` works

A reducer function is in general a function that takes a accumulator (this is an object or value that you can think of as a state that is the result of the previous call to your reducer function) and a data element as parameters and returns a new value/object:
```javascript
(accumulator, element) => resultValue
```
What makes `reduce` very special - in the scope of functional programming - is that it has a state. **Not** the reducer function itself (this one is ideally stateless - to make it easy to test and easy to reuse across your project), but the process of reducing the data itself. Each `accumulator` value gives you the intermediate result of the previous step.

The concept of reducing is especially applied in `Array.prototype.reduce()` (thats probably also the reason for its name). Another well known use of reduce is in the *Redux* state management library. It uses reducer functions in order to change the state in a reproduceable way using an *action* and the current state. The current state is passed as the `accumulator` and the action is the `element` parameter being passed to the reducer. 

## Back to `array.reduce()`

`Array.prototype.reduce()` (or `array.reduce()` of every Javascript instance of Array in JS) iterates over every element of its instance array, starting on the left side (`array[0]`)  of the array, calling your reducer for each element and the result of the reducer for the previous element.

```javascript
const array = [ 1, 2, 3, 5 ];
const finalResult = array.reduce((accumulator, element) => {
	console.log("accumulator: ", accumulator);
	console.log("element: ", element);
	const result = accumulator + element;
	console.log("result: ", result);
	return result;
});
console.log("final result: ", finalResult);

// Console output:
//
// > accumulator: 1
// > element: 2
// > intermediate result: 3
// > accumulator: 3
// > element: 3
// > intermediate result: 6
// > accumulator: 6
// > element: 5
// > intermediate result: 11
// > final result: 11
//
```
The example above seems to be just fine. With a closer look, we can find a fundamental problem, that makes writing more complex reducers not practicable:
The first value that is passed to the `element` parameter of our reducer is actually the second value in the array while the actual first array value is passed to as the `accumulator` value at the first invocation.
**Why is this a problem?**
For more complex reducers, it would mean that we have to distinguish between the first invocation and following invocations, since the first accumulator value might be of completely different type than the array elements are (leading to potential `undefined is not a function` exceptions during execution, when not carefully handled.
Before you now instantly close this article and start writing reducers that can handle data of the type of array elements AND accumulator type:

**`Array.prototype.reduce()` provides a way to completely avoid this problem:**

It allows you to specify a second parameter, next to your reducer function, to be used as the first `accumulator` value. Setting this parameter will completly avoid this problem:

```javascript
const array = [ 1, 2, 3, 5 ];
const finalResult = array.reduce((accumulator, element) => {
	console.log("accumulator: ", accumulator);
	console.log("element: ", element);
	const result = accumulator + element;
	console.log("result: ", result);
	return result;
}, 0);
console.log("final result: ", finalResult);

// Console output:
//
// > accumulator: 0
// > element: 1
// > intermediate result: 1
// > accumulator: 1
// > element: 2
// > intermediate result: 3
// > accumulator: 3
// > element: 3
// > intermediate result: 6
// > accumulator: 6
// > element: 5
// > intermediate result: 11
// > final result: 11
//
```

And it also allows us to pass a different accumulator type (but with same interface), to alter the way data is reduced completely:


```javascript
const array = [ 1, 2, 3, 5 ];
const finalResult = array.reduce((accumulator, element) => {
	console.log("accumulator: ", accumulator);
	console.log("element: ", element);
	const result = accumulator + element;
	console.log("result: ", result);
	return result;
}, "ConcatedElements: ");
console.log("final result: ", finalResult);

// Console output:
//
// > accumulator: ConcatedElements: 
// > element: 1
// > intermediate result: ConcatedElements: 1
// > accumulator: ConcatedElements: 1
// > element: 2
// > intermediate result: ConcatedElements: 12
// > accumulator: ConcatedElements: 12
// > element: 3
// > intermediate result: ConcatedElements: 123
// > accumulator: ConcatedElements: 123
// > element: 5
// > intermediate result: ConcatedElements: 1235
// > final result: ConcatedElements: 1235
//
```
Using a string as first `accumulator` value, will concat the the elements, instead of adding them.

### Available in Different Flavours

Besides `Array.prototype.reduce()` there is also `Array.prototype.reduceRight()`. This is basically the same thing, but operates into the opposite direction:

```javascript
const array_left = ['1', '2', '3', '4', '5'];
const array_right = ['1', '2', '3', '4', '5'];

const left = array_left.reduce((accumulator, element) => {
    return accumulator + element;
});

const right = array_right.reduceRight((accumulator, element) => {
    return accumulator + element;
});

const equivalentRight = array_left.reverse().reduce((accumulator, element) => {
    return accumulator + element;
});

const equivalentLeft = array_right.reverse().reduceRight((accumulator, element) => {
    return accumulator + element;
});

console.log(left);            
console.log(right);           
console.log(equivalentRight);
console.log(equivalentLeft);

// Console output:
//
// > "12345"
// > "54321"
// > "54321"
// > "12345"
//
```

That's it, for this short introduction on `array.reduce()`. Maybe you know some handy recipes for reducers (e.g. grouping data, unifying data, transforming an array into an Object (maybe to use it later as hashmap) or any other idea, you are welcome to post it into the comments. I will include the recipes (with a link to the author) in my next article about reducers.
I also appreciate any feedback, critics or corrections.

I hope this article helps to put more **Fun** into *Functional Programming* ;-)