[flaviocopes] The JavaScript Fundamentals Course - JavaScript Arrays

Introduction

An array is a collection of elements.

Arrays in JavaScript are not a type on their own.

Arrays are objects .

We can initialize an empty array in these 2 different ways:

const a = []
const a = Array()

The first is using the array literal syntax . The second uses the Array built-in function.

You can pre-fill the array using this syntax:

const a = [1, 2, 3]
const a = Array.of(1, 2, 3)

An array can hold any value, even value of different types:

const a = [1, 'Flavio', ['a', 'b']]

Since we can add an array into an array, we can create multi-dimensional arrays, which have very useful applications (e.g. a matrix):

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

matrix[0][0] //1
matrix[2][0] //7

You can access any element of the array by referencing its index, which starts from zero:

a[0] //1
a[1] //2
a[2] //3

You can initialize a new array with a set of values using this syntax, which first initializes an array of 12 elements, and fills each element with the 0 number:

Array(12).fill(0)

You can get the number of elements in the array by checking its length property:

const a = [1, 2, 3]
a.length //3

Note that you can set the length of the array. If you assign a bigger number than the arrays current capacity, nothing happens. If you assign a smaller number, the array is cut at that position:

const a = [1, 2, 3]
a //[ 1, 2, 3 ]
a.length = 2
a //[ 1, 2 ]

Internally, arrays are objects . Running typeof on an array tell you object :

typeof [] //object

You can check if an object is an array by checking its constructor property:

[].constructor === Array //true

while a regular object will have

{}.constructor === Object //true

Adding to an array

Append a single item

To append a single item at the end of an array, use the push() method provided by the Array object:

const fruits = ['banana', 'pear', 'apple']
fruits.push('mango')

push() mutates the original array.

To create a new array instead, use the concat() Array method:

const fruits = ['banana', 'pear', 'apple']
const allfruits = fruits.concat('mango')

Notice that concat() does not actually add an item to the array, but creates a new array, which you can assign to another variable, or reassign to the original array (declaring it as let , as you cannot reassign a const ):

let fruits = ['banana', 'pear', 'apple']
fruits = fruits.concat('mango')

You can add at the beginning of an array using the unshift() method:

const fruits = ['banana', 'pear', 'apple']
fruits.unshift('orange')

fruits //[ 'orange', 'banana', 'pear', 'apple' ]

Append multiple items

To append a multiple item to an array, you can use push() by calling it with multiple arguments:

const fruits = ['banana', 'pear', 'apple']
fruits.push('mango', 'melon', 'avocado')

You can also use the concat() method you saw before, passing a list of items separated by a comma:

const fruits = ['banana', 'pear', 'apple']
const allfruits = fruits.concat('mango', 'melon', 'avocado')

or an array:

const fruits = ['banana', 'pear', 'apple']
const allfruits = fruits.concat(['mango', 'melon', 'avocado'])

Remember that as described previously this method does not mutate the original array, but it returns a new array.

Removing from an array

Removing a single element

There are 2 methods that mutate the original array, and return the element that was removed: pop() and shift() .

This is how you can remove an item from the end of an array:

const fruits = ['banana', 'pear', 'apple']
fruits.pop() //apple
fruits //[ 'banana', 'pear' ]

From the beginning of an array:

const fruits = ['banana', 'pear', 'apple']
fruits.shift() //banana
fruits //[ 'pear', 'apple' ]

To remove elements at a random position in the middle of the array, you can use splice() (not to be confused with slice() ):

a.splice(0, 2) // get the first 2 items
a.splice(3, 2) // get the  2 items starting from index 3

All the method that follow do not mutate the original array , and instead create a new one.

Except splice() , which mutates the original array.

Remove an item you know its index

Suppose you have an array, and you want to remove an item in position i .

One method is to use slice() :

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i-1).concat(items.slice(i, items.length))
// ["a", "b", "d", "e", "f"]

slice() creates a new array with the indexes it receives. We create a new array, from start to the index we want to remove, and concatenate another array from the first position following the one we removed to the end of the array.

Remove an item you know its value

In this case, one good option is to use filter() , which offers a more declarative approach:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)
// ["a", "b", "d", "e", "f"]

This uses the ES6 arrow functions. You can use the traditional functions to support older browsers:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})
// ["a", "b", "d", "e", "f"]

or you can use Babel and transpile the ES6 code back to ES5 to make it more digestible to old browsers, yet write modern JavaScript in your code.

Removing multiple items

What if instead of a single item, you want to remove many items?

Removing all elements

First let’s see how to remove all elements from an array. You can set its length to 0:

const list = ['a', 'b', 'c']
list.length = 0

Another method changes the original array reference, assigning an empty array to the original variable, so it requires using let instead of const :

let list = ['a', 'b', 'c']
list = []

Remove multiple items by index

You can just create a function and remove items in series:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "d", "e"]

Remove multiple items by value

You can search for inclusion inside the callback function:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

Searching in an array

In this lesson I introduce you these 5 methods which can all help in searching an item in the array:

  • indexOf()
  • lastIndexOf()
  • find()
  • findIndex()
  • includes()

It’s great to know them all, but includes() is the most recently (2016) introduced one and I think the one you should use the most. Let’s see them in details.

indexOf()

a.indexOf()

Returns the index of the first matching item found, or -1 if not found

lastIndexOf()

a.lastIndexOf()

Returns the index of the last matching item found, or -1 if not found

find()

a.find((element, index, array) => {
  //return true or false
})

Returns the first item that returns true. Returns undefined if not found.

A commonly used syntax is:

a.find(x => x.id === my_id)

The above line will return the first element in the array that has id === my_id .

findIndex()

findIndex returns the index of the first item that returns true, and if not found, it returns undefined :

a.findIndex((element, index, array) => {
  //return true or false
})

includes()

includes() returns a true boolean value if the element is included in the array, or false otherwise:

if (![1,2].includes(3)) {
  console.log('Not found')
}

Sorting an array

Sort the array

Sort alphabetically (by ASCII value - 0-9A-Za-z )

const a = [1, 2, 3, 10, 11]
a.sort() //1, 10, 11, 2, 3

const b = [1, 'a', 'Z', 3, 2, 11]
b = b.sort() //1, 11, 2, 3, Z, a

Sort by a custom function

const a = [1, 10, 3, 2, 11]
a.sort((a, b) => a - b) //1, 2, 3, 10, 11

Reverse the sort order of an array

a.reverse()

Extract items from an array

Copy an existing array by value

const b = Array.from(a)
const b = Array.of(...a)

Copy just some values from an existing array

const b = Array.from(a, x => x % 2 == 0)

Copy portions of an array into the array itself, in other positions

const a = [1, 2, 3, 4]
a.copyWithin(0, 2) // [3, 4, 3, 4]
const b = [1, 2, 3, 4, 5]
b.copyWithin(0, 2) // [3, 4, 5, 4, 5]
//0 is where to start copying into,
// 2 is where to start copying from
const c = [1, 2, 3, 4, 5]
c.copyWithin(0, 2, 4) // [3, 4, 3, 4, 5]
//4  is an end index

The spread operator

You can expand an array, an object or a string using the spread operator ... .

Let’s start with an array example. Given

const a = [1, 2, 3]

you can create a new array using

const b = [...a, 4, 5, 6]

You can also create a copy of an array using

const c = [...a]

This operator has some pretty useful applications. The most important one is the ability to use an array as function argument in a very simple way:

const f = (foo, bar) => {}
const a = [1, 2]
f(...a)

(in the past you could do this using f.apply(null, a) but that’s not as nice and readable)

Iterating an array

You can use many different ways to iterate an array.

for

for (let i = 0; i < a.length; i += 1) {
  //a[i]
}

Iterates a , can be stopped using return or break and an iteration can be skipped using continue

forEach

a.forEach(f)

Iterates f on a without a way to stop

Example:

a.forEach(v => {
  console.log(v)
})

for…of

for (let v of a) {
  console.log(v)
}

Every

a.every(f)

Iterates a until f() returns false

Some

a.some(f)

Iterates a until f() returns true

Joining multiple arrays

You can join multiple arrays by using concat() , which does not mutate the original arrays:

const a = [1, 2]
const b = [3, 4]
a.concat(b) //[1,2,3,4]
a //[1,2]
b //[3,4]

You can also use the spread operator:

const c = [...a, ...b]
c //[1,2,3,4]

Transform an array into a string

a.toString()

Returns a string representation of an array

a.join()

Returns a string concatenation of the array elements. Pass a parameter to add a custom separator:

a.join(', ')

Arrays of objects

In this lesson I highlight some operations you can perform on arrays of objects .

Sort an array of objects by a property value

Say you have an array of objects like this:

const list = [
  { color: 'white', size: 'XXL' },
  { color: 'red', size: 'XL' },
  { color: 'black', size: 'M' }
]

You want to render this list, but first you want to order it by the value of one of the properties. For example, you want to order it by the color name, in alphabetical order: black, red, white.

You can use the sort() method of Array , which takes a callback function, which takes as parameters 2 objects contained in the array (which we call a and b ):

list.sort((a, b) => (a.color > b.color) ? 1 : -1)

When we return 1, the function communicates to sort() that the object b takes precedence in sorting over the object a . Returning -1 would do the opposite.

The callback function could calculate other properties too, to handle the case where the color is the same, and order by a secondary property as well:

list.sort((a, b) => (a.color > b.color) ? 1 : (a.color === b.color) ? ((a.size > b.size) ? 1 : -1) : -1 )

Get the unique properties of an array of objects

Given an array of objects, here’s what you can do if you want to get the values of a property, but not duplicated.

Suppose you have a bills array with this content:

const bills = [
  { date: '2018-01-20', amount: '220', category: 'Electricity' },
  { date: '2018-01-20', amount: '20', category: 'Gas' },
  { date: '2018-02-20', amount: '120', category: 'Electricity' }
]

and you want to extract the unique values of the category attribute of each item in the array.

Here’s what you can do:

const categories = [...new Set(bills.map(bill => bill.category))]

Explanation

Set is a new data structure that JavaScript got in ES6. It’s a collection of unique values. We put into that the list of property values we get from using map() , which how we used it will return this array:

['Electricity', 'Gas', 'Electricity']

Passing through Set, we’ll remove the duplicates.

... is the spread operator, which will expand the set values into an array.

Quiz

Welcome to the quiz! Try to answer those questions, which cover the topics of this module.

You can also write the question/answer into the Discord chat, to make sure it’s correct - other students or Flavio will check it for you!

  • what is the type of an array?
  • which are the various ways we can use to add an element to an array?
  • explain how to remove an item from an array
  • what is the best way to search the index of an element contained in the array?
  • illustrate the ways we can use to iterate an array
  • imagine we have 2 arrays: ['a', 'b'] and ['c', 'd'] . How can you join them and get an array with ['a', 'b', 'c', 'd'] ?
  • use the sort() method of an array to sort ['d', 'b', 'a', 'c'] to sort by alphabetical order and get ['a', 'b', 'c', 'd']
  • create a bi-dimensional array or 3x3 cells, to generate a matrix with all the numbers from 1 to 9 (1-2-3, 4-5-6, 7-8-9)
  • how can we get the number of items contained in an array?
  • how can you change the value stored in a specific position of the array?