Higher Order Functions: Each, Map, & Filter
Tags: javascript, codenewbie
Published: 2020-04-04 23:50:57

Hello everyone! I'm currently at the end of my fifth week at my coding school, and it's honestly been a pretty rough week. I've spent about three days trying to get a database to actually work, and I'm still unsuccessful! But a wise man once told me, "It is what it is", so I figured that I would write about something today that I actually understand: higher order functions. 

Higher order functions might sound complicated to someone that's relatively new to code; I know that they definitely were to me! However, they're not complicated. A higher order function is just a function that takes in another function as its argument. And I know you might be asking me, "Nico, how can you pass a function into another function?" And I'm glad you asked! A function can be passed into another function just like any other data type can!

Let's take a look at my creation at one of the simplest higher order functions, each:

{% runkit %}

var each = function(collection, action) {
  if (Array.isArray(collection)) {
    for (var i = 0; i < collection.length; i++) {
      action(collection[i], i, collection);
    }
  } else {
    for (var key in collection) {
      action(collection[key], key, collection);
    }
  }
};

{% endrunkit %}

The each H.O.F is a function that takes either an array or an object, and iterates through it. That's all it does! This is so useful so we can stop making long and convoluted for loops of for in loops every time we want to iterate through something.  

If you want an example of how we would use this each function, let me show you the next higher order function I wanted to talk about, Map: 

{% runkit %}

var map = (collection, func) => {
  let mapArray = [];
  each(collection, (element, index, collection) => {
    mapArray.push(func(collection[index]));
  });
  return mapArray;
};

{% endrunkit %}

Before I dive into just what a map function does, take a look at line three. Do you see how I'm using the each function? Of course I could I used a for loop right there, but it is a lot cleaner to make reusable functions instead of having to write them out every single time that you want to use them. The argument that I'm passing through each is a function that is pushing into my result array the result of calling our callback function on every element in the collection array that someone would pass through. And that's the purpose of map: to run a function through every element in a an array and return a new array with the results for each element. This is how someone would use map: 

{% runkit %}

let myArray = [1, 2, 3, 4, 5];
map(myArray, number => number * 2);
//returns [2, 4, 6, 8, 10]

{% endrunkit %}

Map is one of the most important higher order functions you can! Now takes a look at one that I have never used since I learned it, but I think it really helps drill in just what higher order functions are useful for.

{% runkit %}

var filter = (array, func) => {
  let resultArray = [];
  each(array, (element, index, arr) => {
    if (func(element, index, arr) === true) {
      resultArray.push(element);
    }
  });
  return resultArray;
};

{% endrunkit %}

Filter is a higher order function that iterates through every element in an array or object and runs a callback function through every element. Every element that equates to true is then pushed into an array with all of the other elements that equaled to and that result array is returned. I don't think that I've ever had to use this function in a practical sense yet, but it is good to know because it lets you see all the different ways you can use higher order functions.

While I had to painstakingly learn all of these functions in the beginning of my learning, you don't ever have to do that! All of these higher order functions are available in the underscore library. I suggest you take a look if you want to learn more about the usefulness of higher order functions.