Jarrod Watts

Jarrod Watts

What Are JavaScript Higher Order Functions? .map, .filter, and .reduce explained!

What Are JavaScript Higher Order Functions? .map, .filter, and .reduce explained!

Introduction

Higher order functions in JavaScript such as map reduce and filter can completely transform the way you write your code. They are some of the most useful functions when it comes to manipulating data from regular arrays to fit any condition or format you desire.

In this guide, we'll quickly go over how you can utilize these functions, how they work step-by-step, and some common use cases for you to utilize them in your projects.

Why Higher Order Functions?

One of the core concepts of functional programming is the treatment of functions as first-class entities.

This means we can pass functions as arguments to other functions, store functions in variables, and return a function from another function.

Functional programming stems from the declarative paradigm, in which you describe "what" the program should do, rather than the exact steps on how to do it.

Something that has drastically improved the way I write my code is writing in a more declarative manner.

An example of what this looks like is, rather than the traditional for loops that I'm sure you are all familiar with, that look like this:

// Imperative style programming - describing "how" to do it.
const arr = [1,2,3,4,5];
let arr2 = [];

for (let i = 0; i < arr.length; i++) {
    arr2[i] = arr[i]+1
}

console.log(arr2)  // [2,3,4,5,6]

We can convert our code to be much cleaner, with a more declarative style of coding:

// Declarative style programming - describing "what" to do.
const arr2 = [1,2,3,4,5].map((i) => i + 1)

console.log(arr2)  // [2,3,4,5,6]

While this example is very simple, the benefits of writing in this way are well worth it:

  • Cleaner code (Easy to quickly understand and easier to write)
  • Immutability (No opportunity to directly mutate initial array)
  • Less chance of bugs in our manually written for loop.

All of the functions that we are going to discuss in this blog post apply a function to each element of an array; and meet the criteria of being a higher-order function, due to the passing of a function as an argument.

Let's get into the details of the functions map, filter, and reduce now.

Map Function

The JavaScript map function allows you to apply a function to all elements of an array.

map will output a new array, containing the result of running each item in the array through a function that you provide.

In our previous example above, we applied a function that added 1 to each item in an array.

Image Example

carbon (35).png

In the above example, we are applying an imaginary cook function, to each item in the array.

Here is how this works:

  • In sequential order, grab the next item in the array
  • Apply the function to the item (in this case cook)
  • Place the item returned from the applied function at the end of a newly created array.
  • Repeat this process until there are no more items in the initial array.

My favourite use case of the map function is to transform an array of items into React components.

For example, let's say I have an array of peoples names:

const names = ['Jarrod Watts', 'Sandeep Panda', 'Syed Fazle Rahman']

I can convert this list of names into React Components (in this example, just plain HTML) while inside JSX, by using map and passing a function to transform each name in the array, into a new <li> element.

<ul>
  { names.map((name) => (
      <li>${name}</li>
    )) }
</ul>

The output of this code would be:

<ul>
  <li>Jarrod Watts</li>
  <li>Sandeep Panda</li>
  <li>Syed Fazle Rahman</li>
</ul>

Filter Function

The filter function returns a new array of items, which pass the criteria of a predicate function.

In simpler terms, we pass in an array of items, as well as a "test", and run each item of the array through that test.

If the item passes the test, it is included in the output array. If the item fails the test, it is not included in the output array.

Image Example

carbon (45).png

Here's how this works, for each item in the initial array:

  • Run the item through the test function
  • If the item passes the test, include it in the output array
  • Repeat for each item in the array.

An example use case for the filter function is to filter out any undefined data you might have in an array.

For example,

const data = ["hashnode", "is", undefined]

// We could filter out the undefined data by saying
const filteredData = data.filter((x) => x != undefined)

console.log(filteredData ) // ["hashnode", "is"]

Reduce Function

reduce is usually considered the scariest of the three!

Reduce allows you to convert an array into a single output value. The output can be almost anything, a number, a string, another array, or even an object.

Reduce is a bit different to map and filter, because it keeps an accumulator value in addition to the current item being iterated over.

This is different to map and filter which do not have an accumulator value, and simply use the current item.

After iterating over all the items in the array, the accumulator value is the value that gets returned.

Image Example

carbon (44).png

Let's try and break down how a real example of reduce works.

The most simple example of reduce is to add up all the numbers in an array. Let's review how that is possible:

const arr = [1,2,3,4]

const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue);

console.log(sum) // 10

Notice how the function we are passing in now takes 2 parameters.

The first parameter, accumulator is the represents the result of all outputs that have occurred thus far.

The currentValue is what we have seen in before in map and filter; where we can access the current item being iterated over.

What does it mean when we're talking about the accumulator representing the "result of all outputs that have occurred so far"? Let's break it down step by step:

The flow of the example reduce function we are demonstrating below is what happens at every step of the way. If it's not clear, we are attempting to produce the sum of all items in an array.

// Since we don't pass in a default value (which you CAN do),
// accumulator is the first item in the array: 1.
arr.reduce((accumulator, 

// currentValue is then the next item in the array: 2
currentValue) => 

// Define a function to do something with accumulator and currentValue
accumulator + currentValue)

// First iteration:
  // Accumulator = 1
  // CurrentValue = 2
    // 1 + 2 = 3
    // Accumulator is now 3

// Second iteration:
  // Accumulator = 3
  // CurrentValue = 3
    // 3 + 3 = 6
    // Accumulator is now 6

// Third iteration:
  // Accumulator = 6
  // CurrentValue = 4
    // 6 + 4 = 10
    // Accumulator is now 10

// No more items in array

// Return final value of accumulator: 10

Conclusion

In this quick blog post, we've explored three of the most powerful functions in JavaScript:

  • map
  • filter
  • reduce

In addition, we've explored the benefits of using these higher-order functions and why they are so special in the JavaScript world!

Outro

If you enjoyed this kind of content, consider giving me a follow on Hashnode!

I also am active on a number of other social platforms, posting content just like this! I'd love for you to check them out:

If you're feeling really generous, you can support me with Hashnode's Sponsor feature - which all goes directly to me, and then invested back into more content like this!

Sponsor Me 👉 blog.jarrodwatts.com/sponsor ❤️

Thanks for reading!

Interested in reading more such articles from Jarrod Watts?

Support the author by donating an amount of your choice.

Recent sponsors
 
Share this