Mastering the Art of Array Wizardry with Higher-Order Functions

Discover the power of array HOFs and method chaining to transform your data like a true JavaScript wizard

Jason Wandrag
7 min readJan 21, 2023

--

In JavaScript, an array higher-order function (HOF) is a powerful magic spell that can take one or more arrays as arguments, or that returns an array as a result. These spells are a type of higher-order function, which is a spell that takes a function as an argument or returns a function as a result.

Array HOFs are commonly used to perform magical operations on arrays, such as filtering, mapping, reducing, and sorting. They allow you to weave concise and expressive incantations for manipulating arrays, and are an essential tool in any wizard’s arsenal.

Here are some examples of array HOFs in JavaScript:

  • Array.prototype.filter(): This spell takes a callback function as an argument and returns a new array with only the elements that pass a test specified by the callback function.
  • Array.prototype.map(): This spell takes a callback function as an argument and returns a new array with the results of calling the callback function on every element in the original array.
  • Array.prototype.reduce(): This spell takes a callback function as an argument and applies the callback function to each element in the array, accumulating a single result.
  • Array.prototype.sort(): This spell takes a compare function as an argument and sorts the elements of the array in place.

A powerful feature of array methods, are that they can be chained together. Chaining array methods in JavaScript can be thought of as similar to weaving a complex magical incantation because it involves combining multiple functions or spells to achieve a desired result.

When you chain array methods, you call one array method on an array and then call another array method on the result of the first method, and so on. This allows you to perform multiple operations on an array in a single line of code, which can make your code more concise and expressive.

For example, you might chain the filter(), map(), and sort() methods to filter an array, transform the elements, and sort the resulting array all in one line of code.

In this way, chaining array methods is similar to weaving a complex magical incantation because it involves combining multiple functions or spells to achieve a desired result. Just as a wizard might combine multiple spells to create a complex incantation, you can combine multiple array methods to create a powerful and expressive array transformation.

Filtering an Array

As a wizard, I can tell you that filtering and sorting arrays is a common task in JavaScript. To filter an array, you can use the powerful Array.prototype.filter() method. This method allows you to create a new array that includes only the elements that meet certain criteria, as defined by a callback function that you provide.

For example, suppose you have an array of numbers and you want to create a new array that includes only the even numbers. You can do this by using the filter() method like this:

const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // Output: [2, 4]

Sorting an Array

To sort an array, you can use the Array.prototype.sort() method. This method allows you to rearrange the elements of the array in a particular order. By default, the sort order is based on the Unicode code point values of the elements, which means that the elements are sorted as strings. However, you can also provide a custom sort function if you want to sort the elements in a different way.

For example, suppose you have an array of numbers and you want to sort them in ascending order. You can do this by using the sort() method like this:

const numbers = [5, 3, 1, 4, 2];
const sortedNumbers = numbers.sort((a, b) => a - b);
console.log(sortedNumbers); // Output: [1, 2, 3, 4, 5]

Mapping an Array

As a wizard, I have the power to transform arrays of values using the magic of the Array.prototype.map() spell. This spell allows me to apply a function to each element in an array and return a new array with the transformed elements.

For example, if I want to double the values in an array of numbers, I can use the following incantation:

const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(number => number * 2);
console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]

In this incantation, I call the map() spell on the numbers array and pass a function as an argument. The function takes a single argument, number, which represents each element in the array in turn. The function multiplies each element by 2 and returns the result.

The map() spell then returns a new array with the transformed elements. In this case, the new array is [2, 4, 6, 8, 10].

This spell allows me to apply a function to each element in an array and return a new array with the transformed elements.

A more common use case is to format data to include extra information. For example, if I want to add new properties and methods to every object in an array of people, I can use the following incantation:

const people = [
{ name: 'John', surname: 'Doe', age: 30 },
{ name: 'Jane', surname: 'Smith', age: 25 },
{ name: 'Jim', surname: 'Johnson', age: 35 },
{ name: 'Jill', surname: 'Williams', age: 20 }
];

const updatedPeople = people.map(person => {
return {
...person,
fullName: `${person.name} ${person.surname}`,
greeting: function() {
return `Hello, my name is ${this.fullName}`;
}
};
});

console.log(updatedPeople);
// Output: [
// { name: 'John', surname: 'Doe', age: 30, fullName: 'John Doe', greeting: [Function: greeting] },
// { name: 'Jane', surname: 'Smith', age: 25, fullName: 'Jane Smith', greeting: [Function: greeting] },
// { name: 'Jim', surname: 'Johnson', age: 35, fullName

In this incantation, I call the map() spell on the people array and pass a function as an argument. The function takes a single argument, person, which represents each element in the array in turn.

The function returns a new object that includes the original object spread using the spread operator (...) and two new properties: fullName, which is a string that combines the name and surname properties, and greeting, which is a function that returns a string with a greeting.

The map() spell then returns a new array with the transformed elements. In this case, the new array is updatedPeople, which includes the new properties and methods for each object.

Chaining Array Methods

As a skilled spellcaster, I have the power to chain together multiple spells to achieve my desired result. For example, if I want to sort an array of numbers in ascending order, select only the even numbers, and multiply each number by 2, I can use the following incantation:

const numbers = [5, 3, 1, 4, 2];
const sortedNumbers = numbers
.sort((a, b) => a - b) // Sort the numbers in ascending order
.filter(number => number % 2 === 0) // Select only the even numbers
.map(number => number * 2); // Multiply each number by 2
console.log(sortedNumbers); // Output: [4, 8]

In this incantation, I am able to chain together the sort(), filter(), and map() spells to transform the numbers array in a single statement.

To chain spells in JavaScript, I simply need to call one spell after another on the same object or value. Most spells in JavaScript return the object or value on which they were called, allowing me to call another spell on the result. This is known as spell chaining.

It is easy to see why chaining is a useful concept, however we rarely get to use an array of primitives. More often than not, we deal with large arrays of objects that describe data belonging to users, products or posts that are provided over a REST API endpoint.

In the example below, I fetch a large array of users from the random user API. Once I receive a response from the server, I apply a filter() to select all males who are over the age of 18, then I chain on my sort() method to order the users by age first, then by name in alphabetical order. Finally, I am able to chain on the map() method so that I can change the structure of the data to include a fullName property. This is a handy spell to format our data into a more developer friendly data structure.

const url = "https://randomuser.me/api/?results=5000";

fetch(url)
.then(response => response.json())
.then(data => {
const people = data.results;

const filteredSortedPeople = people
.filter(person => person.gender === 'male' && person.dob.age > 18)
.sort((a, b) => {
// Sort by age in ascending order
if (a.dob.age !== b.dob.age) {
return a.dob.age - b.dob.age;
}
// If ages are equal, sort by name in ascending order
return a.name.first.localeCompare(b.name.first);
})
.map(person => {
return {
...person,
fullName: `${person.name.first} ${person.name.last}`
};
});

console.log(filteredSortedPeople);
})
.catch(error => console.error(error));

I hope these incantations help you wield the power of JavaScript to filter and sort and format arrays to your will!

Contact me here: LinkedIn | Codepen | Email

--

--

Jason Wandrag

With a passion for front end development, I am aiming to make the web a beautiful place by innovating how we consume information and interact with the web.