Writing cleaner code with higher-order functions

Writing cleaner code with higher-order functions


Higher-order functions in JavaScript simply put are functions that either return another function or take another function as an argument.

There are built-in higher-order functions in JavaScript which we’ll be looking at in a bit, first, let’s look at the simplest example of a higher-order function:


const add = (x)=>(y)=> x + y;

As you can see from what I said earlier, the function add above is returning another function, which makes add itself a higher-order function.

Built-in higher-order functions

There are quite a number of built-in higher-order functions on the array object which makes our code cleaner and more understandable.

We could look at these higher-order functions as utility functions which we call, then pass a set of arguments to perform some operation then return a value to us.

To consider the length of this article, we’re on going to be covering the four most used higher-order function, which are:

  1. The map function
  2. The filter function
  3. The reduce function
  4. The sort function

The map function

I will be using the map function to demonstrate an action done without a higher-order function, and then using the map function to show how much more elegant the code could be.

Let’s look at this scenario where we want to increment all the numbers in an array by two:


const arr = [2, 4, 6, 8];

 //using a for loop to iterate over the elements and adding two

const incremented = [];

for (let i = 0; i < arr.length; i++){
  increment.push(arr[i] + 2);
}
console.log(incremented) // [4, 6, 8, 10]


// using the map function

const new_array = arr.map(elem => elem + 2);
console.log(new_array); // [4, 6, 8, 10]

See how we reduced the calculation to just one line? I’ll take some time to explain what’s happening there now.

Higher-order functions exist on the array prototype object, so they’re available for use on all arrays.

And the function passed as an argument typically excepts three arguments, the first is the element from the array in the current iteration, the second is the index of that element, and the third is the array to which that element belongs.

Although not all functions passed to a higher-order function look like that, there is an exception for the reduce and sort functions listed above, we’ll have a deeper look into those later in the article.

The filter function

The filter function returns a set of elements from the original array that meet the parameters set:


const numbers = [-1, 2, 3, 9, 6, -6]
const positive_numbers = numbers.filter(elem => elem >= 0);
console.log(positive_numbers) // [2, 3, 9, 6]

It doesn’t stop there, you can easily filter out elements based on their data types by just passing in the function name:


const mixed = ['hello', 'world', 4, 5, 'google']
const numbers = mixed.filter(Number);
console.log(numbers); // [4, 5]

You can also pass in the Boolean function to filter out truthy values from the array.

The reduce function

To put things simply, the reduce function can take a complex array, perform an operation and return a single value:


const numbers = [1, 2, 3, 4, 5, 6]
numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 21

The function above sums up all the numbers in the given array and returns a single value.

The reduce function takes in two arguments, the first is the callback function to be executed, and the second is the initial value to start from.

If I changed the initial value from the code snippet above to two, the function would start from two, then continue with the first element of the array, like this:

2+1+2+3+4+5+6 = 23;

You would also notice that the callback passed has two parameters, the call back accepts four parameters in total.

  1. The accumulator
  2. The current value
  3. The current index
  4. The source array

The reducer’s returned value is stored in the accumulator after each iteration which is then returned as the final value after the operation is complete.

check out this resource on MDN for better understanding.

The sort function

The sort function sorts the elements in an array and returns the sorted array, the order is ascending by default.

Also, the sort function sorts elements as strings and compares them based on their UTF-16 code. For that reason, when sorting numerical values, 20 is greater than 100000, that’s because “2” is greater than “1”.

Remember that the default sorting order is ascending, so 20 should come before 100000, but:


const numbers = [20, 4, 100000, 4];
numbers.sort(); // [100000, 20, 4, 4]

When using the sort method on an array, a copy is not made but instead mutated directly. For example:


const a = [5, 6, 3, 4, 9, 2];
const b = a.sort();
console.log(b); //[2, 3, 4, 5, 6, 9]
a; //[2, 3, 4, 5, 6, 9]

So, b just points to the sorted array a, it’s not a copy of it.

We can change the sort order by specifying that in a compare function.

Since the default sorting order of the sort function is ascending, in some cases we might want the reverse, thankfully we can pass in a compare function to the sort method to specify the order we want.

Going back to our previous example on sorting numerical values, if we passed in a compare function:


const a = [5, 600, 3, 4, 9, 2];
const b = a.sort((a,b)=> a - b); // ascending order
console.log(b); // [2, 3, 4, 5, 9, 600]

The compare function used above specified that the sort order should be ascending, to specify a descending order, we simply swap the position of a and b in the function’s return statement.


const a = [5, 600, 3, 4, 9, 2];
const b = a.sort((a,b)=> b - a); // descending order
console.log(b); // [600, 9, 5, 4, 3, 2]

How the compare function works is that it should return a negative, zero or positive value depending on the arguments.

The sort function tries to compare two values by sending them to the compare function, the compare function then returns a numerical value.

  • If the value is negative, a is placed before b.
  • If the value is positive, b is placed before a.
  • Finally, if the is zero, no changes are done in the order.

Two more higher-order functions you could check out are some() and every().

Finally, it’s possible to chain higher-order functions

You can perform another action on the value returned from a higher-order function immediately it’s returned:

Take a look of this operation that adds two to all array elements then filters out only numerical elements.


const mixed = ['hello', 'world', 2, 4, 6, 'maize'];

mixed.map(elem => elem + 2).filter(Number); // [4, 6, 8]


There are a lot of actions that could be performed on arrays that have been simplified by higher-order functions. Start using higher-order functions in your code today.


Share on social media

//