The Use-Case-Driven Guide to Essential JavaScript Array Methods

by Adam Davis

Table of contents:

When working with arrays, it can be easy to reinvent the wheel.

Once you know how to iterate over an array with a for loop, you can sink into the trap of using it every time you’re working with arrays.

Any why shouldn’t you? After all, it’s a versatile, easily understood concept.

The importance of logical shorthands

When a pattern occurs frequently across many different types of programs, developers create utility functions for handling those patterns.

Not only does this cut down on duplicate code, but the semantics helps other developers understand your intent more easily.

You can write a loop that filters an array, but when I see Array.filter I immediately know what you’re trying to do.

How does this guide work?

I’ve gone through the instance methods of JavaScript arrays and organized them by category, leaving out the ones that I consider to be less commonly used.

Did I leave out your favorite array method? Let me know in the comments!

Sample Data

The below sample data is used throughout this post. To maintain consistency, each example starts with the assumption that this data has not been modified.

// Some Hosts of Great British Bake Off
const hosts = [
	{ id: 1, name: 'Paul Hollywood', isBaker: true },
	{ id: 2, name: 'Prue Leith', isBaker: true },
	{ id: 3, name: 'Noel Fielding', isBaker: false },
	{ id: 4, name: 'Matt Lucas', isBaker: false },
];

// Some Winners of Great British Bake Off
const winners = [
	'Edd Kimber',
	'Joanne Wheatley',
	'John Whaite',
	'Frances Quinn',
];

Testing or looking for existing elements

Find the first element that satisfies a condition

Array.prototype.find()

find accepts a function and returns the first element for which that function returns a truthy value.

const paul = hosts.find(host => host.name === 'Paul Hollywood');
// { id: 1, name: 'Paul Hollywood', isBaker: true }

const firstNonBaker = hosts.find(host => !host.isBaker);
// { id: 3, name: 'Noel Fielding', isBaker: false }

Find the index of the first element that satisfies a condition

Array.prototype.findIndex()

This method works the same way as find, except it returns the element’s index instead of the elements itself.

const paulIndex = hosts.findIndex(host => host.name === 'Paul Hollywood');
// 0

Find the index of an element

Array.prototype.indexOf()

indexOf differs slightly from findIndex in that it accepts an exact value as its parameter rather than function. Because of this, it’s more useful for primitive values since objects are compared by reference.

If the element occurs more than once in the array, the index of the first occurrence is returned.

If the element is not in the array, then -1 is returned.

const indexOfJohn = winners.indexOf('John Whaite');
// 2

const indexOfMe = winners.indexOf('Adam Davis');
// -1
// This methods compares objects by reference rather than by value, so it's 
// more useful with primitive types than with objects.
const originalPaul = hosts[0];
const paulClone = { id: 1, name: 'Paul Hollywood', isBaker: true };

const indexOfOriginalPaul = hosts.indexOf(originalPaul);
// 0

const indexOfPaulClone = hosts.indexOf(paulClone);
// -1

Find the last index of an element

Array.prototype.lastIndexOf()

This is the same as indexOf except it returns the index of the last occurrence of an element except the first occurrence of an element.

Find every element that satisfies a condition

Array.prototype.filter()

const bakers = hosts.filter(host => host.isBaker);
// [ { id: 1, name: 'Paul Hollywood', isBaker: true }, { id: 2, name: 'Prue Leith', isBaker: true } ]

Test whether every element satisfies a condition

Array.prototype.every()

const isAllBakers = hosts.every(host => host.isBaker);
// false

Test whether at least one element satisfies a condition

Array.prototype.some()

const hasAtLeastOneBaker = hosts.some(host => host.isBaker);
// true

const hasAtLeastOneIdGreaterThanTen = hosts.some(host => host.id > 10);
// false

Test whether an element is included in an array

Array.prototype.includes()

// This methods compares objects by reference rather than by value, so it's 
// more useful with primitive types than with objects.
const originalPaul = hosts[0];
const paulClone = { id: 1, name: 'Paul Hollywood', isBaker: true };

const containsOriginalPaul = hosts.includes(originalPaul);
// true

const containsPaulClone = hosts.includes(paulClone);
// false

Manipulating arrays

Note: Each of these examples assumes the array is in the original state and has not been changed by another example

Add an element to the end of an array

Array.prototype.push()

hosts.length;
// 4

hosts.push({id: 5, name: 'Sue Perkins'});

hosts.length;
// 5

// This method accepts an arbitrary number of arguments, meaning you can add as
// many elements as you want with a single call

winners.length;
// 4

winners.push('Nancy Birtwistle', 'Nadiya Hussain', 'Candice Brown');

winners.length;
// 7

Array.prototype.concat()

While this is not the only use case for concat, it can be used in the same way as push. The difference, however, is that concat is non-destructive. This means that it returns a new array instead of the overwriting the existing array.

winners.length;
// 4

const moreWinners = winners.concat('Nancy Birtwistle', 'Nadiya Hussain', 'Candice Brown');

winners.length;
// 4

moreWinners.length;
// 7

Remove the last element from an array

Array.prototype.pop()

This method is the inverse of push, removing the last element from an array. Using these two functions, you can treat an array like a stack.

hosts.length;
// 4

const lastElement = hosts.pop();
// { id: 4, name: 'Matt Lucas', isBaker: false }

hosts.length;
// 3

Combine two arrays

Array.prototype.concat()

winners.length;
// 4

otherWinners = ['Sophie Faldo', 'Rahul Mandal'];

combinedWinners = winners.concat(otherWinners);

Set all (or just some) elements to the same value

Array.prototype.fill()

winners.fill('everyone');
// [ 'everyone', 'everyone', 'everyone', 'everyone' ]

winners.fill('you', 0, 2);
// [ 'you', 'you', 'everyone', 'everyone' ]

Sort an array

Array.prototype.sort()

winners.sort();
// [ 'Edd Kimber', 'Frances Quinn', 'Joanne Wheatley', 'John Whaite' ]

Reverse the order of an array

Array.prototype.reverse()

winners;
// [ 'Edd Kimber', 'Joanne Wheatley', 'John Whaite', 'Frances Quinn' ]

winners.reverse();
// [ 'Frances Quinn', 'John Whaite', 'Joanne Wheatley', 'Edd Kimber' ]

Reduce the depth of an array (unnest an array of arrays)

Array.prototype.flat()

let bothArrays = [hosts, winners];
// [
//   [
//     { id: 1, name: 'Paul Hollywood', isBaker: true },
//     { id: 2, name: 'Prue Leith', isBaker: true },
//     { id: 3, name: 'Noel Fielding', isBaker: false },
//     { id: 4, name: 'Matt Lucas', isBaker: false }
//   ],
//   [ 'Edd Kimber', 'Joanne Wheatley', 'John Whaite', 'Frances Quinn' ]
// ]

bothArrays.flat();
// [
//   { id: 1, name: 'Paul Hollywood', isBaker: true },
//   { id: 2, name: 'Prue Leith', isBaker: true },
//   { id: 3, name: 'Noel Fielding', isBaker: false },
//   { id: 4, name: 'Matt Lucas', isBaker: false },
//   'Edd Kimber',
//   'Joanne Wheatley',
//   'John Whaite',
//   'Frances Quinn'
// ]

Iterating over or performing functions on elements of an array

Get the results of passing each element into a function

Array.prototype.map()

const hostNames = hosts.map(host => host.name);
// [ 'Paul Hollywood', 'Prue Leith', 'Noel Fielding', 'Matt Lucas' ]

Array.prototype.flatMap()

flatMap works the same way as map, but flattens the array afterwards.

const hostNamesSeparated = hosts.flatMap(host => host.split(' '));
// [
//   'Paul', 'Hollywood',
//   'Prue', 'Leith',
//   'Noel', 'Fielding',
//   'Matt', 'Lucas'
// ]

Iterating over every element

Array.prototype.forEach()

hosts.forEach(host => console.log(host.name));
// Paul Hollywood
// Prue Leith
// Noel Fielding
// Matt Lucas

Reduce an array into a single value

Array.prototype.reduce()

I think reduce is usually a good candidate for replacing a for loop when there’s a variable declared right before the loop, and the main purpose of the loop is to accumulate some value in that variable.

// The for loop you might want to replace
let numberOfBakers = 0;
for (let i = 0; i < hosts.length; i++) {
	numberOfBakers = numberOfBakers + ~~hosts[i].isBaker;
	// ~~ is used to convert values to numbers without allowing for NaN
}
let numberOfBakers = hosts.reduce((accumulator, host) => accumulator + ~~host.isBaker, 0);
// 2

Creating string representations

Array.prototype.join()

join creates a string representation of the array, delimiting each item using the given string argument.

winners.join(', ');
// 'Edd Kimber, Joanne Wheatley, John Whaite, Frances Quinn'

Array.prototype.toString()

winners.toString();
// 'Edd Kimber,Joanne Wheatley,John Whaite,Frances Quinn'

Adam Davis

Share this post: