JavaScript — Recreating The Map/Filter/Reduce Higher Order Functions

Henry Nguyen
Nov 8 · 5 min read

This article will discuss how you can create your own map, filter and reduce higher-order functions. They were introduced in ECMAScript 2015 and have become the staples for looping through arrays.

The Map Function

The map function allows us to create a new array with new values in each index. Let’s have a look at a basic implementation below:

const myArray = [1, 2, 3, 4, 5];
const newArray = myArray.map((currentValue, index, currentArray) => {
return currentValue + 1;
});
// newArray output -> [2, 3, 4, 5, 6]

We’ve created an array myArray and used the map function to loop over each value and added 1 to it and stored the new array in newArray.

As we can see, the map function requires a callback function with the parameters currentValue, index, and the currentArray. Now let’s attempt to recreate the higher order function:

Array.prototype.myMapFn = function(callback) {
let result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, array));
}
return result;
};

The above myMapFn higher order function is utilising the Prototype Global Object Constructor on the Array object and accepts a callback as a parameter.
We first need to declare an empty array, result, where we will store the new values we obtain from the callback function. Then we need call the callback function for every iteration of the array and pass the currentValue, index, and currentArray to it and push each result to the result array. Then finally we simply return the result array.

We can put it into action like so:

const array = [1, 2, 3];
const newArray = array.myMapFn((value, i, array) => {
return value + 1;
});
// newArray output -> [2, 3, 4]

The Filter Function

The filter function allows us to loop through an array and specify what we want to filter and return those values in a new array.
Let’s have a look at a basic implementation below:

const data = [
{name: 'Henry', team: 'yellow'},
{name: 'Toby', team: 'red'},
{name: 'Tracy', team: 'red'},
{name: 'Flavio', team: 'blue'},
{name: 'Dustman', team: 'green'}
];
const filteredArray = data.filter((player, index, array) => {
return player.team === 'red'
});
// filteredArray output -> [{name: 'Toby', team: 'red'},{name: 'Tracy', team: 'red'}]

We’ve created an array called data storing players name and their team and used the filter function to return players who belong to the red team.

As we can see, the filter function requires a callback function with the parameters currentValue, index, and the currentArray — similar to the map function. Now let’s attempt to recreate the higher order function:

Array.prototype.myFilterFn = function(callback) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
result.push(this[i]);
}
}
return result;
};

The above myFilterFn higher order function is similar to the custom map function we created earlier in terms of logic structure however this time the callback function within the loop will be used as a condition for the if statement. If the condition is true, the current player data within the loop will be pushed to the result array.

We can put it into action like so:

const data = [1, 1, 3, 4, 5];
const newArray = data.myFilterFn((value, i, array) => {
return value === 1;
});
// newArray output -> [1, 1]

The Reduce Function

The reduce function reduces an array to a single value and executes a provided function for each value of an array. The return result is stored in an accumulator.

Let’s have a look at a basic implementation below:

const data = [1,2,3];
const result = data.reduce((accumulator, value, index, array) => {
return accumulator + value;
}, 0);
// result output -> 6

The above example takes an array and sums up all of the values within that array and outputs it. As we can see, the accumulator is the second argument for the reduce higher order function, which is set to 0. For every iteration, the result of the logic gets stored in the accumulator.

The accumulator can also be an array or object. Let’s take a look at another example below:

const fruits = ['apple', 'pear', 'pear', 'watermelon'];
const result = fruits.reduce((acc, value, index, array) => {
if (!acc[value]) {
acc[value] = 1;
} else {
acc[value]++;
}
return acc;
}, {});
// result output -> {apple: 1, pear: 2, watermelon: 1}

In the above example, we are counting the amount of fruits we have and saving the results in an object.

Now let’s attempt to recreate the reduce function:

Array.prototype.myReducerFn = function(callback, accumulator) {
let result = accumulator || this[0];
for (let i = 0; i < this.length; i++) {
if (!accumulator && i === 0) {
} else {
result = callback(result, this[i], i, this);
}
}
return result;
};

The above myReducerFn higher order function takes two arguments; the first being the callback, that accepts 4 arguments in the following order; accumulator, value, index, and array. As mentioned earlier, the accumulator is where the result will be stored. The second argument is the accumulator itself — think of this as the initial value.

In the logic, we first need to declare a result variable that holds the initial value of the accumulator or first value of the array if the accumulator does not exist. We then need to declare a loop that calls the callback function on every iteration and pass the accumulator value, current value, index and array as the callback arguments. The result of the callback will be stored in the results variable we declared earlier and be compounded for every iteration.

Lets see it in action:

const array = [1, 2, 3];
const result = array.myReducerFn((accumulator, value, i, array) => {
accumulator.push(value + 1);
return accumulator;
}, []);
// result output -> [2, 3, 4]

Summary

This article has covered the implementation of the map, filter and reduce functions with basic examples. I hope it was helpful to understand how the those higher order functions work under the hood. Please comment down if you found it helpful.

Henry Nguyen

Written by

Frontend Software Engineer based from Perth, Australia.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade