Higher Order Array Functions forEach, map and filter

9 min read views

Array methods such as forEach(), map() and filter() are some of the Higher Order Array Functions that come in very handy when you have to work with data that's in an Array.

In this article we'll be discussing the following Higher-Order Functions, with examples :

I'll be assuming that you have a basic understanding of what Higher-Order Functions are and how to work with them, if not, I recommend you read my previous article on it.

Array.forEach()

forEach() method is very useful to perform certain operation(s) for every element in the Array.

The forEach() method on an Array executes the provided callback function for each element in the array in ascending index(starting 0).

Syntax

forEach(callbackFn)
forEach((element, index, array) => {
  /* ... */
})
forEach(callbackFn)
forEach((element, index, array) => {
  /* ... */
})
Parameters

callbackFn
Function to execute on each element. It accepts one to three arguments :

element : The current element being processed in the array.
index : The index of element in array.
array : The array on which forEach() was called upon.

The forEach() method doesn't return anything : undefined

If you look at the signature of the callback function in this method, it looks similar to the forEach() function that I created in the previous Higher-Order Functions article.

Examples

Let's recreate the same example now using the Array.forEach() method :

const numbs = [5, 9, 10, 1] // Array of numbers
 
numbs.forEach((n, i, arr) => {
  // n => element, i => index, arr => array(numbs)
  arr[i] = n + 2 // add 2 to current element
})
 
numbs.forEach(n => console.log(n)) // logs all element one-by-one
// 7
// 11
// 12
// 3
const numbs = [5, 9, 10, 1] // Array of numbers
 
numbs.forEach((n, i, arr) => {
  // n => element, i => index, arr => array(numbs)
  arr[i] = n + 2 // add 2 to current element
})
 
numbs.forEach(n => console.log(n)) // logs all element one-by-one
// 7
// 11
// 12
// 3

As the forEach() is a method on the array itself, we can call it on any array using the dot notation.

In the above example we've called Array.forEach() Higher-Order function twice with arrow functions as callbacks, defined right withing forEach()'s parameters.

Say we have an Array of full names and you are required to separate all the full names into firstName and lastName of an object and push them into an array that already contains same kind-of data. How'd you do it?

const fullNames = [
  "Adam Benson",
  "Clare Donaldson",
  "Ben Adams",
  "Donald Clarkson",
]
const fullNames = [
  "Adam Benson",
  "Clare Donaldson",
  "Ben Adams",
  "Donald Clarkson",
]

Here's how you can use the forEach() to push objects containing firstName and lastName property to the names array.

const names = [{ firstName: "Anil", lastName: "Seervi" }]
 
fullNames.forEach(n => {
  const obj = {} // empty object for initialization
  [obj.firstName, obj.lastName] = n.split` ` // split at spaces and destructure initialize
  names.push(obj) // push the object to names array
})
 
console.log(names)
/*
[
  { firstName: 'Anil', lastName: 'Seervi' }
  { firstName: 'Adam', lastName: 'Benson' },
  { firstName: 'Clare', lastName: 'Donaldson' },
  { firstName: 'Ben', lastName: 'Adams' },
  { firstName: 'Donald', lastName: 'Clarkson' }
]
*/
const names = [{ firstName: "Anil", lastName: "Seervi" }]
 
fullNames.forEach(n => {
  const obj = {} // empty object for initialization
  [obj.firstName, obj.lastName] = n.split` ` // split at spaces and destructure initialize
  names.push(obj) // push the object to names array
})
 
console.log(names)
/*
[
  { firstName: 'Anil', lastName: 'Seervi' }
  { firstName: 'Adam', lastName: 'Benson' },
  { firstName: 'Clare', lastName: 'Donaldson' },
  { firstName: 'Ben', lastName: 'Adams' },
  { firstName: 'Donald', lastName: 'Clarkson' }
]
*/

In the above example, within our callback, we create an empty object obj to store the properties. Then we split the current element of the array at spaces, destructure it right away storing it to properties firstName and lastName in the object obj. At last we push the object into the names array.

Array.map()

Array.map() method comes very handy when you have to create a new array from executing a certain function on an existing array.

The Array.map() method on an Array returns a new array populated with the return value of the callback function called for every element in an array in ascending index(starting 0).

Syntax

map(callbackFn)
map((element, index, array) => {
  /* ... */
})
// returns a new array populated with results of callbackFn
map(callbackFn)
map((element, index, array) => {
  /* ... */
})
// returns a new array populated with results of callbackFn
Parameters

callbackFn
Function to execute on each element of arr. Each time callbackFn executes, the return value is added to the newArray. It accepts one to three arguments :

element : The current element being processed in the array.
index : The index of element in array.
array : The array on which map() was called upon.

Return value

The map() method returns a new Array with each element being the result of the callback function.

Examples

Let's assume we are given the following array and are told to produce another array of consisting of the sqaures of all the respective elements.

const numbs = [5, 9, 10, 1] // our boring array of numbers
const numbs = [5, 9, 10, 1] // our boring array of numbers

The easiest way to do this will be by using the Array.map() method :

const squares = numbs.map(n => n ** 2)
// Yes, its easy as that!!
 
console.log(numbs)
// [ 5, 9, 10, 1 ]
console.log(sqaures)
// [ 25, 81, 100, 1 ]
const squares = numbs.map(n => n ** 2)
// Yes, its easy as that!!
 
console.log(numbs)
// [ 5, 9, 10, 1 ]
console.log(sqaures)
// [ 25, 81, 100, 1 ]

That was so easy right. All we need to do is to call the map() method on our numbs array and return the square of the current element within it for our logic. As the map() method itself returns a new Array, we store it in the variable sqaures.

Now let's look at another example where we'll convert an array of objects with firstName and lastName properties that we got as our output in the forEach() and create another array which will consist of only full names. Kinda the reverse of what we did in forEach() example.

// array of objects with firstName and lastName
const names = [
  { firstName: "Anil" },
  { firstName: "Adam", lastName: "Benson" },
  { firstName: "Clare", lastName: "Donaldson" },
  { firstName: "Ben", lastName: "Adams" },
  { firstName: "Donald", lastName: "Clarkson" },
]
 
// create a new Array of fullNames using names Array
const fullNames = names.map(name => {
  const full_name = `${name.firstName} ${name?.lastName || ""}`
  return full_name.trimEnd()
})
 
console.log(fullNames)
// [ 'Anil', 'Adam Benson', 'Clare Donaldson', 'Ben Adams', 'Donald Clarkson' ]
// array of objects with firstName and lastName
const names = [
  { firstName: "Anil" },
  { firstName: "Adam", lastName: "Benson" },
  { firstName: "Clare", lastName: "Donaldson" },
  { firstName: "Ben", lastName: "Adams" },
  { firstName: "Donald", lastName: "Clarkson" },
]
 
// create a new Array of fullNames using names Array
const fullNames = names.map(name => {
  const full_name = `${name.firstName} ${name?.lastName || ""}`
  return full_name.trimEnd()
})
 
console.log(fullNames)
// [ 'Anil', 'Adam Benson', 'Clare Donaldson', 'Ben Adams', 'Donald Clarkson' ]

Above, the first thing you'll notice while looking at the example is we don't have lastName property for my name and our logic will have to handle that too.

Within the callback of our map() method we are using template literals to concatenate firstName and lastName(if any: using optional chaining) to form the full_name. And returning trimmed full_name from the callback.

Array.filter()

As the name implies, this method is used to filter out the array which meets a certain condition.

Array.filter() method on the Array returns an new Array with only the elements that pass the test condition within the callback function.

Syntax

filter(callbackFn)
filter((element, index, array) => {
  /* ... */
})
// returns a new array with elements that satisfy the callback condition.
filter(callbackFn)
filter((element, index, array) => {
  /* ... */
})
// returns a new array with elements that satisfy the callback condition.
Parameters

callbackFn
Function is a predicate to execute on each element of arr. Each time callbackFn is called, only the element's that coerce to true are added into the new Array. It accepts one to three arguments :

element : The current element being processed in the array.
index : The index of element in array.
array : The array on which filter() was called upon.

Return Value

The filter() method returns a new Array with only the elements that satisfy the test condition in the callbackFn.

Examples

To keep it easier to understand I'm taking our same old numbs array to work on.

const numbs = [5, 9, 10, 1, 6, 3] // hey, I'm bigger this time :)
const numbs = [5, 9, 10, 1, 6, 3] // hey, I'm bigger this time :)

lets pose a couple question so to filter our boring array.

Q1

Obtain an array of Odd Numbers from numbs

const odd = numbs.filter(n => n % 2 !== 0)
 
console.log(odd)
// [ 5, 9, 1, 3]
const odd = numbs.filter(n => n % 2 !== 0)
 
console.log(odd)
// [ 5, 9, 1, 3]

Within the callback, we return true only for odd numbers in our array which in-turn returns all odd numbers in our numbs array.

Q2

Obtain an array of Prime Numbers from numbs

function isPrime(numb) {
  for (let i = 2, s = Math.sqrt(numb); i <= s; i++)
    if (numb % i === 0) return !1
  return numb > 1
}
 
console.log(numbs.filter(isPrime))
// [ 5, 3 ]
function isPrime(numb) {
  for (let i = 2, s = Math.sqrt(numb); i <= s; i++)
    if (numb % i === 0) return !1
  return numb > 1
}
 
console.log(numbs.filter(isPrime))
// [ 5, 3 ]

Here isPrime is our callback for filter method which gets called with every element in numbs and acts as our condition to filter out numbers that are prime.

Below is a composite example of both map() and filter() methods. I'm going to create an Array that'll contain names of my GitHub Repos which are majorly written with SCSS.

The example is an async IIFE(Immediately Invoked Function Expression) Function that'll get called as soon as it's defined. Within our async function, I'm fetching the data related to my GitHub repos in JSON format using GitHub's REST API.

The API returns an Array of Objects that contain information about my public GitHub repositories listed alphabetically. You can see the response of the API by visiting the below URL:

The API only returns a maximum of 30 repos without any query parameters.

;(async function jsRepos() {
  const res = await fetch(
    "https://api.github.com/users/AnilSeervi/repos?per_page=100"
  ) // fetch the JSON from API
  const data = await res.json() // parse JSON to JavaScript Object
 
  const filterJSRepos = data.filter(i => i.language === "SCSS") // filter the Repos based on language
  const repoNames = filterReposData.map(i => i.name) // Create an array of filtered Repo names
 
  console.log(repoNames)
  // ['DevFolio', 'mdn-minimalist', 'ts-portfolio']
})()
;(async function jsRepos() {
  const res = await fetch(
    "https://api.github.com/users/AnilSeervi/repos?per_page=100"
  ) // fetch the JSON from API
  const data = await res.json() // parse JSON to JavaScript Object
 
  const filterJSRepos = data.filter(i => i.language === "SCSS") // filter the Repos based on language
  const repoNames = filterReposData.map(i => i.name) // Create an array of filtered Repo names
 
  console.log(repoNames)
  // ['DevFolio', 'mdn-minimalist', 'ts-portfolio']
})()

The response(in JSON) fetched from the URL is stored in res and then converted to a JavaScript Object that is stored in data.

Note: The names and number of repos may change based on the time you are reading this. Now we have an Array of objects of all the repos which we need to be filtered based on the language property. Objects whose language property is SCSS are filtered into filterJSRepos constant.

After filtering the Repos, we can now grab just the name property of the filtered Repos using map() and voila, there's our array that contains the names of my repos those majorly contain SCSS.

I hope this article helped you understand the Higher-Order Array Functions(forEach(), map(), filter()).

Thank you for reading my blog. Let's connect on Twitter!.

cd ..

Subscribe for updatesDiscuss on TwitterSuggest Change