# Arrays

# Introduction

In JS an array is an ordered collection of inhomogeneous elements, each element can be of a different kind (string, number, boolean, etc), which means we can have different types of elements grouped in one place. Also it can be defined as a special variable which can hold more than one value at a time.

# Creating arrays in JS

There are two main ways to create an array in JS:

  1. Defining with brackets delimiting with commas the elements of our array
  2. Using the 'new' keyword followed by array ()
const numbers = [10, 20, 30];
const months = new Array('January', 'February', 'March');

In JS each element of the array has an index that denotes the position of each one within the array which begins to count from 0 in an increasing way.

# Structure of an array

  • Index: Position of our element, also known as key.
  • Value: Element within position

To better understand this structure of the array, we will use our previous defined "numbers" array, inside the console.log() function at the console from the developer tool of our browser or also known as the debugging console. In the following way:

Example 1. Showing the numbers array at the console

console.log(numbers);

// Expected output: Array [10, 20, 30]

Example 2. Showing the months array at the console

console.log(months);

// Expected output: Array [January, February, March]

In both structures of the previous examples, we can see how the console represents the index or the key in each element followed by the value of each position in our array.

How many positions can an array have? An array can have from 1 to many positions and it could even be empty as follows:

const numbers = [];

Do the elements of an array have to be the same type? Not necessarily, we can create arrays of different types of data.

Example 3. We will create an array with 3 types of data: string, number and boolean.

var person = ["July", 22, true]; 

// Showing what the console throws us
console.log(person);

// Expected output: Array ["July", 22, true]

Can we declare one array within another one? Yes, we can define as many arrays as we want within any position of our main array.

Example 4. We will declare an array of numbers, within our "person" array.

var combinedArray = ["July", 22, true, [1, 2, 3, 4] ];

As shown it is possible to compose our array.

# Accessing the values of an array

We can access to the value of an array by using indexes, that's why they are so important. To understand it better, let's apply the following example:

  1. We create a new array of numbers with 5 values
const numbers = [10, 20, 30, 40, 50];

In our console, if we apply the console.log(numbers) function, we can see the indexes of each element of our array. Another way to see the indexes more explicitly could be by applying the console.table() function:

console.table(numbers) || console.log(numbers)

  1. We access the position we want from our array If we want to access the value 30, we can see in the table that its index is 2, then we will use that index to access the value in the following way:
console.log(numbers[2]);
// Expected output: 30

Our console will show us the value 30 since we accessed the element through its key or index. So successively we will do for each value of the array, we will access through its index with the syntax shown.

Note: If we try to access an index or position of the array that does not yet exist, JS will return an "undefined" value.

Example 1. Accessing to a nonexistent array position

console.log(numbers[5]); 

According to our table shown above, our array contains 5 positions, but in JS the indexes start to count from 0, therefore if we try to access index 5, we will be trying to access a value that does not exist, so in those cases we will get “undefined”.

# Walkthrough an array

If we create an array of months of the year, we can try to access each of the values by its index:

const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];


console.table(months);
// Expected output: Array ["January", "February", "March", "April", "May", "June", "July"]
console.table(months[0]);
// Expected output: January
console.table(months[1]);
// Expected output: February
console.table(months[2]);
// Expected output: March

However, what would happen if we don't know how many positions the array has and we need to go through each of the elements?

First we need to know the length of our array, for that we use the length property

console.log(months.length)
// Expected output: 7

This property will indicate us the length of the array so we can use it later.

Now to go through the array we will use an iterator, in this case we will implement a for loop.

The for loop is a function that has 3 parts delimited by commas on the following order:

  1. The value at which the array will begin to iterate is defined [We define a variable].
  2. Here we define the condition of how the code is going to be executed [The block of code runs until the defined condition is met].
  3. Variable incrementer [So that it goes to the next position and so on].

Our for loop will show each element on the array from position 0 to the last. So It prints the position dynamically to avoid accessing one by one.

Example 1. Iterating over months array

for (let i = 0; i < months.length; i++ ) {
   console.log(months[i]);
}

// Expected output: Array ["January", "February", "March", "April", "May", "June", "July"]

We got in our console the printing of our months one by one.

# Adding new elements to an array

Arrays can be modified even though they are declared as constants (const):

By its index (Position)

const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
months[0] = 'New Month';

This action will change the value of "January", which represents the first position in our array, as a result we would see that “January” will change to “New Month”, so if we print this in the console, we will see:

# Adding a new position to the array

Now, if we also want to add a new position to our array, for example a position 7

months[7] = 'Last Month';

We would see this output:

We could also create our new element in any other position in our array, for example if we wanted to create it in position 10:

months[10] = 'X month';

As a result we would expect this output:

As we can see on the previous example, in cases like these, JS will simply skip the positions that we have omitted or that do not exist yet, creating the new position with the index that we have indicated.

Cons: When adding positions in this way, we have to know exactly which elements are in our array. However the common case would be when we don't know them because there are many elements, so the most convenient thing will be to use the array methods which comes within the JS language to add positions at the end or at the beginning of our array. We will see about those methods below.

We will see how to add new elements to the end or beginning of an array (Imperative way)

Note: Imperative form is because it will modify the form of our array, while the declarative way won't.

# Using JS's push method

The push() method adds new items to the end of an array, and returns the new length.

const months = ['February', 'March', 'April'];

// Adding at the end of my array the new month
months.push('May');
// Expected output: Array ["February", "March", "April", "May"]

# Using JS's unshift method

The unshift() method adds new items to the beginning of an array, and returns the new length.

const months = ['February', 'March', 'April', 'May'];

// Adding my new month to the beginning of the array
months.unshift('January');
// Expected output: Array ["January", "February", "March", "April", "May"]

As a result we got our month of January added to the beginning of our array.

Example. Using push/unshift with an online shopping cart.

Assuming we have an online shopping cart, initially we give it to our client empty so that they can start adding products to it. So:

  1. We start with an empty array
  2. We define two products as objects
  3. We add both to the end of the array by using our push method
  4. Now let's define a third product and we add it to the beginning of our array by using unshift method
  5. Let's check at the console how looks our array
const cart = [];

// Defining a product
const product = {
    name: "32 Inch Monitor",
    price: 400
}


const product2 = {
    name: "Cell phone",
    price: 800
}

// .push to add at the end of our array

cart.push(product2);
console.log(cart);
// Expected output: Array [{ name: "Cell phone", price: 800 }]

cart.push(product);
console.log(cart);
// Expected output: Array [{ name: "Cell phone", price: 800 }, { name: "32 Inch Monitor", price: 400 }]


const product3 = {
    name: 'Keyboard',
    price: 50
}

cart.unshift(product3);
console.log(cart);
// Expected output: Array [{ name: "Keyboard", price: 50 }, { name: "Cell phone", price: 800 }, { name: "32 Inch Monitor", price: 400 }]

# Adding new elements to the array using the spread operator (Declarative way)

The 'Spread operator' available in Javascript ES6 helps us to unpack elements in an array into single / individual arguments. It is written by means of three consecutive points, one after the other (...). They are like the ellipsis of traditional writing. Its operation is quite simple, as we will see below.

Example

  1. We create a first array with three elements.
  2. We create a second array with an element in the first position and then, we will pass to our new array all the elements of the first array that we create using our spread operator.
const arr = ["Joy", "Wangari", "Warugu"];
const newArr = ["joykare", ...arr];

So newArr will be:

[ 'joykare', 'Joy', 'Wangari', 'Warugu' ]

Our spread operator unpacked each one of the elements of our first array in the second, keeping the same order.

# Remove values from an array

# Using JS's pop method

The pop method will remove the last position of our array

Example

newArr = [1, 2, 3, 4, 5];

// Removing the element on the last position of the array, so we will remove the number 5
newArray.pop()

// Expected output: [1, 2, 3, 4]

# Using JS's shift method

The shift method will remove the first position of our array

Example

newArr = [1, 2, 3, 4, 5];

// Removing the element of the first position of the array, so we will remove the number 1
newArray.shift()

// Expected output: [2, 3, 4, 5]

# Using JS's splice method

The splice method allow us to remove a position of our array from any position of it, we just have to indicate which element by passing to the method 2 parameters: start and end.

Parameters that receives our splice method: Start: Position from which to start cutting. End: How many items to delete from the beginning.

Example 1: We want to remove the third element of our array, in this case would be number 3

newArr = [1, 2, 3, 4];
newArray.splice(2, 2);

Our new array would be: [1, 2, 4];

Example 2: Remove from the second to the third element of our array, in this cases would be numbers 2 and 3.

newArr = [1, 2, 3, 4];
newArray.splice(1, 2);

Our array would be: [1, 4];

Example 3: We will have an online shopping cart, where our goal will be to remove 2 items that the user no longer wants to buy

const cart = [
    {
        name: "32 Inch Monitor",
        price: 400
    },
    {
        name: "iPhone 11",
        price: 699
    },
    {
        name: "Wireless Keyboard",
        price: 35
    },
    {
        name: "13-inch MacBook Pro",
        price: 1200
    },
];

The user no longer wants to buy the iPhone 11 and the wireless keyboard, those elements in our array correspond to the second and third position, so we proceed to remove them using splice method:

cart.splice(1, 2);

As a result we would have our shopping cart just with the element that the user wants to buy.

# Array destructuring

What does it mean?

Destructuring means taking a value out of the structure

What is the logical syntax to do destructuring on an array?

The syntax to extract values from an array is defined according to the position of the values of the array in ascending order.

Example:

const numbers = [10, 20, 30, 40, 50];

// We access the first element by destructuring

const [first] = numbers;

console.log(first);

// Expected output: 10

Our console showed us a 10 as a result because we are calling the first element when we declared a single value within the destructuring [], it means that we could have given it the name we'd like and the logic would take the first element since we are declaring just one constant.

Then how could we access to the third position in our numbers array ?

const [first, second, third] = numbers;

console.log(third);
// Expected output: 30

In this way, we are choosing the third element of our array, it means that we have to declare the positions of the previous elements that we want to access. So, how can we get that value without declaring the first 2 elements [first, second]?

Here's one way to do that:

const [ , ,third] = numbers;

console.log(third);
// Expected output: 30

As shown at the previous example, we can also leave the positions that we don't want to access as empty, in that way we can still access our third element.

Furthermore, we can also get the remaining elements of the array from a specific position using the spread operator.

const [ , , ...third] = numbers;

console.log(third);

// Expected output: Array [30, 40, 50]

In this case we printed the values ​​= 30, 40, 50 at the console. Because by using our spread operator we are not only accessing to our third position but also the rest of our array, declaring them only once.

What is the difference between an array and an object destructuring?

By destructuring an object, we can access any value of the object using its property name, whereas with an array we cannot.

Example:

const product = {
    name: "32 Inch Monitor",
    price: 400
 };

// Doing destructuring only for price property

const { price } = product;

console.log(price);

// Expected output: 400

At the previous example, we got the price property of the product object and we didn't need to access to the previous property [name] to be able to reach it, while in the case of an array, we will need to access to the previous positions in order to reach the element we want to access. This is because we are searching into the same position of the array.

# Methods to iterate an array in JS

JS presents us easier ways to iterate elements of an array, those methods seek to replace the use of the traditional for loop, also giving us new features that allow simplifying tasks within development.

To begin, we are going to loop through an array using the traditional for loop

  1. We have our array of objects which represents an online shopping cart and each object within the array contains 2 attributes that represents the items in the cart.
const cart = [
    { name: 'Monitor', price: 500 },
    { name: 'TV', price: 100 },
    { name: 'Tablet', price: 200 },
    { name: 'Headphones', price: 300 },
    { name: 'Keyboard', price: 400 },
    { name: 'Phone', price: 700 },
]
  1. We print each item of our array in our console by using a traditional for loop
for (let i = 0; i < cart.length; i++ ) {
    console.log(`${cart[i].name} - Price: ${cart[i].price }` );
}

Example above explained:

  • First, we set a variable where the loop starts (let i = 0;)
  • Then, we define the condition for the loop to run. As long as the variable is less than the length of the array (which is 4), the loop will keep iterating.
  • Each time the loop iterates, the variable is incremented by one (i++)
  • Once the variable is no longer less than 6 (array's length), the condition won't be met and the loop will stop.

Now we’ll try to print the same results but this time by using the methods provided by JavaScript.

# ForEach method

The forEach() method executes a provided function once for each array element. Syntax

arr.forEach(callback(currentValue[, index[, array]]) {
  // execute something
}[, thisArg]);

Parameters

callback Function to execute on each element. It accepts between one and three arguments: currentValue The current element being processed in the array. indexOptional The index of currentValue in the array. arrayOptional The array forEach() was called upon. thisArgOptional Value to use as this when executing callback. Return value

undefined.

With this method we can have the same result that we could get by using for loop but providing a callback function to the method to be more specific with each object that’s gonna be iterated.

Example:

  1. We got the same cart that we had before.
const cart = [
    { name: 'Monitor', price: 500 },
    { name: 'TV', price: 100 },
    { name: 'Tablet', price: 200 },
    { name: 'Headphones', price: 300 },
    { name: 'Keyboard', price: 400 },
    { name: 'Phone', price: 700 },
]
  1. Now we gonna print every item on the array using for each using the following steps
  • Declare the forEach method to the array.
  • Inside the method, declare a function and give as a first parameter a name to identify every object that its gonna be read.
  • Into the block of the callBack function place an action to read the properties that we want to show from every object.
cart.forEach( function(product) {
    console.log(`${product.name} - Price: ${product.price }` );
    // Expected output: Print each cart item
} )

That is how the forEach method iterate every object into the array.

Pros of using forEach method instead of for loop

  • We don’t need to declare the length of the array
  • The callback function inside of the method give us the possibilities to improve our code readability by being more descriptive of what’s going to be read.
  • We don’t lose performance by using it.

# Map method

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

Syntax

let newArray = arr.map(callback(currentValue[, index[, array]]) {
  // return element for newArray, after executing something
}[, thisArg]);

Parameters callback Function that is called for every element of arr. Each time callback executes, the returned value is added to new_array. The callback function accepts the following arguments: currentValue The current element being processed in the array. indexOptional The index of the current element being processed in the array. arrayOptional The array map was called upon. thisArg Optional Value to use as this when executing callback. Return value

A new array with each element being the result of the callback function.

Basically map do the same thing as forEach method but allowing us to create a new array with the result of the mapping.

Example. We gonna iterate the properties of our cart but this time we want to create a new array only with the names of the product into the array.

const cart = [
    { name: 'Monitor', price: 500 },
    { name: 'TV', price: 100 },
    { name: 'Tablet', price: 200 },
    { name: 'Headphones', price: 300 },
    { name: 'Keyboard', price: 400 },
    { name: 'Phone', price: 700 },
]
  1. Let’s iterate our cart and get only the property: name of every object.
const newArrayOfProductNames = cart.map(function(product) {
    return `Product: ${product.name}`;
    // Expected output: Print the name of each product in the cart
});
  1. If we show newArrayOfProductNames in the console we’ll see that a new Array with the names of the products has been created.
console.log(newArrayOfProductNames);
// Expected output: Array with the names of the products

What If we try to do the same using forEach?

const newArrayOfProductNames = cart.forEach(function(product) {
    return `Product: ${product.name}`;
});

console.log(newArrayOfProductNames); 
// Expected output: undefined

The result will be undefined, because forEach method doesn’t create a new array with the results of the iteration.

# Difference between Map & ForEach methods

Let’s first take a look at the definitions on MDN: forEach() — executes a provided function once for each array element. map() — creates a new array with the results of calling a provided function on every element in the calling array.

What exactly does this mean?

  • forEach() method doesn’t return anything (undefined). It simply calls a provided function on each element in your array. This callback is allowed to mutate the calling array.
  • map() method utilizes return values and actually returns a new Array of the same size and also will call a provided function on every element in the array

More Array methods in JS …  Let’s start looking at other common array methods used.

# Filter method

The filter() method creates an array filled with all array elements that pass a test (provided as a function).

Note: filter() does not execute the function for array elements without values and neither change the original array.

In other words, filter creates a new array from the condition we define on the function inside of it, let’s see it with an example:

  1. We have our cart
const cart = [
    { name: 'Monitor', price: 500 },
    { name: 'TV', price: 100 },
    { name: 'Tablet', price: 200 },
    { name: 'Headphones', price: 300 },
    { name: 'Keyboard', price: 400 },
    { name: 'Phone', price: 700 },
];
  1. Now we desire to get from it the products whose price is higher than 400, so we define our filter method with that condition in the function.
result = cart.filter(function(product) {  
    return product.price > 400;
});

console.log(result); // to see our new array in the console
  1. As a result we’ll have a new array called result with the more expensive products (higher than 400).
[
    { name: 'Monitor', price: 500 },
    { name: 'Phone', price: 700 }
]

# Resources