11. Array Higher-Order Methods

Follow along with code examples here!

Table of Contents

Summary

  • Array higher-order methods provide declarative ways to work with arrays, making code more readable and reducing the need for explicit loops.

  • map() transforms each element in an array and returns a new array with the transformed values, useful for converting data formats or applying calculations.

  • filter() creates a new array containing only elements that pass a test condition, perfect for filtering data based on criteria.

  • find() and findIndex() return the first element or index that passes a test, useful for searching arrays.

  • reduce() combines all array elements into a single value, powerful for calculations like sums, averages, or building complex data structures.

  • sort() arranges array elements in order based on a comparison function, with the callback determining the sorting logic.

  • Method chaining allows you to combine multiple array methods for complex data transformations in a readable, functional style.

Imperative vs. Declarative Code: Why we use Higher Order Functions

What is the value of Higher Order Functions? They allow us to write our code in a more declarative manner rather than in an imperative manner.

Imperative code provides explicit instructions for every step to complete a task. This gives us a lot of control over every step, but it takes more effort.

Declarative code just describes the desired solution and uses existing tools to handle the steps. While we give up control to the existing tool, we save time and effort.

For example, suppose we want to double every value in an array. We can either write out every single step imperatively, or we can declaratively describe the desired outcome using array.map

Let's look at how we can use some more array higher-order methods to write more declarative code.

Array Iterators

The most commonly used higher-order functions are these "iterator" array methods:

Method
Description (For every value in the source array...)
Example(s)

array.forEach

Perform a task that produces a side effect using the value

Mutate each value in the array or print each value to the console

array.map

Transform the value and add it to a new array

Double every number in the source array

array.filter

Test the value and add it to a new array if it passes the test

Keep only the even numbers in the source array

array.find

Test the value and return the first value that passes the test

Find the first number in an array that is greater than 10

array.findIndex

Test the value and return the index of the first value that passes the test

Find the index of the first number in an array that is greater than 10

array.reduce

Determine how it can be combined with the other values in the array

Calculate the sum of all numbers in an array

array.sort

Compare it with another value to determine which should go first

Sort an array of numbers in descending order

.map(mutate)

arr.map iterates over the source array, invoking the given callback with each value, index, and the source array arr as inputs. The value returned by the callback is added to an array which is returned.

Use map when you want a copy of the source array with each value converted to a new value.

Example: In this example, we have an array inchesArr containing values each representing a number of inches. Using arr.map, we transform each inches value into a string in the format x inches => y feet z inches. Each of these new strings is added to the array returned by map and stored in feetAndInches:

Challenge: In this example, we have a users array full of user objects. Write a callback for array.map that extract all of the usernames into a new array:

Solution

.filter(test)

arr.filter iterates over the source array, invoking the given callback with each value, index, and the source array arr as inputs. If the callback returns true, the value is added to an array which is returned.

Use filter when you want a copy of the source array with unwanted values removed.

Example: In this example, we want to know how many scores in an array of numbers are greater than or equal to 75. Using arr.filter, we can get a copy of the array containing only those passing scores and then read its length.

Challenge: In this example, we have an array of user objects. We want to get a copy of the array that only contains admins.

Use filter to check each object and keep only those with the property isAdmin: true.

Solution

.find(test) and .findIndex(test)

While .filter is used to get ALL values that pass a test callback, the .find and .findIndex methods are used to get only the first value that passes the test.

Remember, the return value of the callback must return a boolean!

.reduce(accumulate, startingValue)

Unlike the other higher-order array methods, array.reduce() takes in a callback accumulate AND a second argument startingValue.

It is used to "reduce" array values into a single value, built up starting with the startingValue.

  • The callback should accept the accumulated value so far and the current value

  • The callback should return the updated accumulated value

  • .reduce() returns the final accumulated value

.sort(compare)

Another interesting higher-order function is the array method array.sort().

Given an array of numbers, array.sort() will sort them in ascending order, from smallest to largest. It does this in place which means that the source array is modified.

We can change this default behavior though by providing a callback function as an argument:

arr.sort has some particular expectations around the callback function that we provide. It should:

  • Have two parameters, together representing a pair of values in the source array arr to compare. Let's call them a and b.

  • Return -1 (or any negative number) if value a is meant to go before value b.

  • Return 1 (or any positive number) if value a is meant to go after after value b.

  • Return 0 if the order of values a and b does not matter.

Challenge

Implement your own callback function sortAscendingByLength that sorts an array of strings according to their length with shorter strings coming first.

Solution

Tips and Tricks

Using All Callback Parameters

Most of these array higher order methods will iterate through the source array and invoke the given callback with three values:

  1. The current value

  2. The index of the current value

  3. The source array itself

Chaining Array Methods

Generating a Frequency Counter with Reduce

Nested Arrays

Last updated