Complete Guide to JavaScript Arrays

Published on
12 mins read
––– views

One of the fundamental concepts in JavaScript is Arrays. Understanding arrays will make you better JavaScript developer. This article is not introductory to arrays, but it is a complete guide to arrays.

In this article we will explore JavaScript Arrays in detail and the next article we will explore JavaScript Objects.

Create an Array

Arrays can be created in two ways.

// preferred way of creating arrays
const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
const salad = new Array("🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑")

Access Array Item

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
console.log(salad[0]) // First item
console.log(salad[1]) // Seconda item
console.log(salad[-1]) // Last item
console.log(salad[salad.length - 1]) // Last item
console.log(`Salad array contains ${salad.length} salads`)

Add, Change and Remove Array Items

Adding, changing and removing array content are one of the most basic array operations. Refer the following code samples and snippets.

Add item to the last index

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
salad.push("🥜") // ['🥜', '🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']

Add item to the first index

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
salad.unshift("🥜") // ['🥜', '🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']

Remove last array content

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
salad.pop() // ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕']

Remove first array content

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
salad.shift() // ['🍄', '🥦', '🥒', '🌽', '🥕', '🥑']

Array destructuring

Array destructuring is essential concept you need to master to work with data and states in React. Refer the following code snippets.

const [tomato, mushroom, carrot] = ["🍅", "🍄", "🥕"]
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄'
console.log(carrot) // '🥕'

array destructuring with default value

When destructuring arrays you can provide default value if the array item doesn't exist.

const [tomato, mushroom = "🍄"] = ["🍅"]
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄'

destructuring nested array

Consider the following nested array

const fruits = ["🍈", "🍍", "🍌", "🍉", ["🍅", "🍄", "🥕"]]

How would you access the '🥕' from the above array? You could do this without destructuring:

const veg = fruits[4] // returns the array ['🍅', '🍄', '🥕']
const carrot = veg[2] // returns '🥕'

Alternatively, you could use this short-hand syntax:

fruits[4][2] // returns '🥕'

You can also access it using the destructuring syntax, like this:

const [, , , , [, , carrot]] = ["🍈", "🍍", "🍌", "🍉", ["🍅", "🍄", "🥕"]]

array destructuring with rest

You can destructure array items you want to work with and put the rest of the items in a variable

const [tomato, mushroom, ...rest] = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
console.log(tomato) // '🍅'
console.log(mushroom) // '🍄'
console.log(rest) // ["🥦", "🥒", "🌽", "🥕", "🥑"]

skip a value in array destructuring

const [tomato, , carrot] = ["🍅", "🍄", "🥕"]

You could use array destructuring for swapping variable values like this:

let first = "😔"
let second = "🙂"
;[first, second] = [second, first]
console.log(first) // '🙂'
console.log(second) // '😔'

Copy arrays

You can copy an array using slice() array method like this:

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
const saladCopy = salad.slice()
console.log(saladCopy) // ['🍅', '🍄', '🥦', '🥒', '🌽', '🥕', '🥑']
salad === saladCopy // returns false

You can also do the same thing using array destructuring

const salad = ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
const saladCloned = [...salad]
console.log(saladCloned) // ["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]
salad === saladCloned // false

Merge Arrays

We can merge two arrays and create a new array with all the elements from both arrays. Let's take two arrays — one with a couple of smiley faces and another with a few veggies.

const emotion = ["🙂", "😔"]
const veggies = ["🥦", "🥒", "🌽", "🥕"]

Let's merge this two arrays using concat() method. When using this method you don't have a lot of control how the two arrays are merged compared with destructuring. This method does not change the original array.

const emotionalVeggies = emotion.concat(veggies)

We can do this using array destructuring as well.

const emotionalVeggies = [...emotion, ...veggies]
console.log(emotionalVeggies) // ["🙂", "😔", "🥦", "🥒", "🌽", "🥕"]

Array assertions

isArray() method can help you when testing or working with arrays.

Array.isArray(["🍅", "🍄", "🥦", "🥒", "🌽", "🥕", "🥑"]) // returns true
Array.isArray("🍅") // returns false
Array.isArray({ tomato: "🍅" }) // returns false
Array.isArray([]) // returns true

JavaScript Array Methods

So far, we have seen a few array properties and methods. Let's do a quick recap of the ones we've looked at:

  • push() – Insert an element at the end of the array.
  • unshift() – Insert an element at the beginning of the array.
  • pop() – Remove an element from the end of the array.
  • shift() – Remove an element from the beginning of the array.
  • slice() – Create a shallow copy of an array.
  • concat() – Merge two or more arrays together
  • Array.isArray() – Determine if a value is an array.
  • length – Determine the size of an array.

Let's know take a look at some essential JavaScript array methods

includes()

Checks if an item exists in a given array. The method is case sensitive.

const names = ["tom", "alex", "bob", "john"]
names.includes("tom") // returns true
names.includes("july") // returns false

indexOf() and lastIndexOf()

indexOf() method returns the index of the item you are looking for.

const names = ["tom", "alex", "bob", "john"]
names.indexOf("alex") // returns 1
names.indexOf("rob") // returns -1

lastIndex() method returns the index of the last time the item exisited in aan array (If there is duplicate value of the item).

const names = ["tom", "alex", "bob", "tom"]
names.indexOf("tom") // returns 0
names.lastIndexOf("tom") // returns 3

reverse()

reverse() method returns a new array with the items reversed.

const names = ["tom", "alex", "bob"]
console.log(names.reverse()) // returns ["bob", "alex", "tom"]

sort()

The sort() method is probably one of the most often used array methods. The default sort() method converts the element types into strings and then sorts them. The default sorting order is ascending. The sort() method changes the original array.

const names = ["tom", "alex", "bob"]
names.sort() // returns ["alex", "bob", "tom"]

The sort() method accepts an optional comparator function as an argument. You can write a comparator function and pass to the sort() method to override the default sorting behavior.

Let's now take an array of numbers and sort them in ascending and descending order using a comparator function:

const numbers = [23, 5, 100, 56, 9, 13, 37, 10, 1]

First, we'll invoke the default sort() method and see the output:

numbers.sort() // [1, 10, 100, 13, 23, 37, 5, 56, 9]

Now the sorted array is, [1, 10, 100, 13, 23, 37, 5, 56, 9]. Well, that's not the output we expect. But it happens because the default sort() method converts the elements to a string and then compares them based on the UTF-16 code unit values.

To solve this, let's write a comparator function. Here is one for the ascending order:

const ascendingComp = (a, b) => a - b

Now pass this to the sort() method:

numbers.sort(ascendingComp) // retruns [1, 5, 9, 10, 13, 23, 37, 56, 100]

Or you can use shorter version of this

numbers.sort((a, b) => a - b)

For descending order, do this:

numbers.sort((a, b) => b - a)

splice()

The splice() method helps you add, update, and remove elements in an array. This method may be a bit confusing at the beginning, but once you know how to use it properly, you will get it right.

The main purpose of the splice() method is to delete elements from array. It returns an array of the elements deleted and modifies the original array. But you can add and replace elements using it as well.

To add an element using the splice() method, we need to pass the position where we want to add, how many elements to delete starting with the position, and the element to add.

In the example below, we are adding an element zack at the index 1 without deleting any elements.

const names = ["tom", "alex", "bob"]
names.splice(1, 0, "zack")
console.log(names) // ["tom", "zack", "alex", "bob"]

Have a look at the following example. Here we are removing one element from the index 2 (the 3rd element) and adding a new element, zack. The splice() method returns an array with the deleted element, bob.

const names = ["tom", "alex", "bob"]
const deleted = names.splice(2, 1, "zack")
console.log(deleted) // ["bob"]
console.log(names) // ["tom", "alex", "zack"]

Array Iterators

Now let's look at one of the most essential array methods which lets you iterate and operate over a given array. Let's use the following array as jumping point and go over what operations we can perform over this array.

const users = [
{
id: 001,
firstName: "Alex",
lastName: "B",
gender: "M",
age: 22,
paid: 250,
courses: ["JavaScript", "React"],
},
{
id: 002,
firstName: "Ibrahim",
lastName: "M",
gender: "M",
married: true,
age: 32,
courses: ["JavaScript", "PWA"],
},
{
id: 003,
firstName: "Rubi",
lastName: "S",
gender: "F",
married: false,
age: 27,
courses: ["Blogging", "React", "UX"],
},
{
id: 004,
firstName: "Zack",
lastName: "F",
gender: "M",
married: true,
age: 36,
courses: ["Git", "React", "Branding"],
},
]

filter()

The filter() method creates a new array with all the elements that satisfies the condition mentioned in the function. Let's find female users from our array. So the filter condition should be that the gender is equal to 'F'.

const femaleUsers = users.filter((user, index) => {
return user.gender === "F"
})
console.log(femaleUsers)

map()

The map() method creates a new array by iterating through the elements and applying logic we provided in the function as an argument. We'll create a new array of full names of all the users in the users array.

const fullNames = users.map((user, index) => {
return { fullName: user.firtName + " " + user.lastName }
})
console.log(fullNames)

forEach()

This array method calls the given function for each item in the array. The syntax for this method is

_array_.forEach(_function(currentValue, index, arr), thisValue_)
users.forEach((user, index, users) => {
console.log(`user: ${user.firstName} ${user.lastName}`)
})

reduce()

The reduce() method applies a reducer function on each of the array elements and returns an output value. We'll apply a reducer function on the users array to compute the total age of the users.

const totalAge = users.reduce((accumulator, user, currentIndex, array) => {
accumulator = accumulator + user.age
return accumulator
}, 0)
console.log(totalAge)

some()

The some() method returns a boolean value (true/false) based on at least one element in the array passing the condition in the function. Let's see if there are any students below the age 30.

let hasStudentBelow30 = students.some((element, index) => {
return element.age < 30
})
console.log(hasStudentBelow30) // true

Yes, we see there is at least one student younger than 30.

find()

Using the some() method, we have seen that there is a student below age 30. Let's find out who that student is.

To do that, we will use the find() method. It returns the first matched element from the array that satisfies the condition in the function.

Arrays have another related method, findIndex(), that returns the index of the element we find using the find() method. If no elements match the condition, the findIndex() method returns -1.

In the example below, we pass a function to the find() method that checks for the age of each of the student. It returns the matched student when the condition satisfies.

const student = students.find((element, index) => {
return element.age < 30
})
console.log(student)

every()

The every() method detects if every element of the array satisfies the condition passed in the function. Let's find if all the students have subscribed to at least two courses.

const atLeastTwoCourses = students.every((elements, index) => {
return elements.courses.length >= 2
})
console.log(atLeastTwoCourses) // true

As expected, we see that the output is true.

Proposed Array Methods

As of May, 2021, ECMAScript has a method in proposal, the at() method.

The at() Method

The proposed at() method would help you access the elements of an array using a negative index number. As of now, this is not possible. You can access elements only from the beginning of the array using a positive index number.

Accessing elements from the back of the array is possible using the length value. With the inclusion of the at() method, you would be able to access the elements using both positive and negative indexes using a single method.

const junkFoodILove = ["🥖", "🍔", "🍟", "🍕", "🌭", "🥪", "🌮", "🍿"]
junkFoodILove.at(0) // 🥖
junkFoodILove.at(3) // 🍕
junkFoodILove.at(-1) // 🍿
junkFoodILove.at(-5) // 🍕
junkFoodILove.at(-8) // 🥖
junkFoodILove.at(10) // undefined

Here is a quick demo of it:

demo-3

Javascript Array at() method demo

You can use this polyfill to achieve the functionality of the at() method until this method gets added to the JavaScript language.

let array1 = [1, 2, 3, 4, 5]
let [indexOne, indexTwo, indexThree, indexFour, indexFive] = array1
let [indexOne, , , , indexFive] = array1
let array1 = [1, 2, 3, 4, 5]
let array2 = [6, 7, 8, 9, 10]
let array3 = array1.concat(array2)
let array3 = [...array1, ...array2]