A Practical Guide to JavaScript Arrays
Learn basic concepts of an array and its important methods
An array is a data structure used for storing similar values in a linear fashion. Arrays are objects just like everything in JavaScript. Since JavaScript isnโt a typed language, you can store multiple types of data in a single array (not recommended).
// Storing similar data (type string and programming language)
const languages = ["JavaScript", "Python", "Ruby", "Java", "C#", "PHP"];
console.log(typeof languages); // object
// โ Bad use of the array data structure (the object will be a better choice in this case)
const person = ["John", "Doe", 33, true];
Ways of creating an Array
- Using the
Array
constructor (not recommended) - Using the
from
method on theArray
constructor - Using Array Literal
Using Array constructor (not recommended)
Use the new Array
syntax to create an array.
// This will create an empty array
const weapons = new Array(); // []
// Adding elements to the array
weapons.push("๐ซ"); // add an element to the end of the array
weapons.push("๐ช");
weapons.push("๐ฃ");
console.log(weapons); // [ '๐ซ', '๐ช', '๐ฃ' ]
You can also pass in initial values to the Array
constructor.
const weapons = new Array("๐ซ", "๐ช", "๐ฃ");
console.log(weapons); // [ '๐ซ', '๐ช', '๐ฃ' ]
You can also create an empty array with the number of free spaces for the elements. But be careful with this one as this creates an array with 3 empty spaces having undefined
as its value. This will become an issue if we have 100s of empty spaces. Learn more about this issue on this Stackoverflow post.
const weapons = new Array(3);
console.log(weapons); // [ undefined, undefined, undefined ]
Using the from method on the Array constructor
The from
method on Array
creates a new and shallow-copied Array
instance from an array-like OR an iterable object. This is very useful when you want to convert an iterable object to an array.
Converting an array-like object i.e. string
in this case:
const weapons = Array.from("๐ซ ๐ช ๐ฃ");
console.log(weapons); // [ '๐ซ', ' ', '๐ช', ' ', '๐ฃ' ]
Converting an iterable object i.e. Set
in this case (a Set
is an iterable object):
const uniqueWeapons = Set(["๐ซ", "๐ซ", "๐ช", "๐ฃ"]);
console.log(uniqueWeapons); // Set { '๐ซ', '๐ช', '๐ฃ' }
const weapons = Array.from(uniqueWeapons);
console.log(weapons); // [ '๐ซ', '๐ช', '๐ฃ' ]
You learn more about the from
method on the Array
constructor here.
Using Array literal ([])
The preferred way is using the Literal ([]
) syntax.
const weapons = ["๐ซ", "๐ช", "๐ฃ"];
console.log(weapons); // [ '๐ซ', '๐ช', '๐ฃ' ]
Accessing elements in an Array
Elements in an array are indexed. These indexes are used for accessing elements with a time complexity of O(1) which is really fast. The numbering for these indexes starts with zero (0).
const food = ["๐ burger", "๐ pizza", "๐ fries", "๐ฅช sandwich", "๐ฎ taco"];
console.log(food[0]); // ๐ burger, first element of the array
console.log(food[1]); // ๐ pizza
console.log(food[2]); // ๐ fries
console.log(food[food.length - 1]); // ๐ฎ taco, last element of the array
If you try to use an index that is out of bound (i.e. greater than equal to the length of an array then the output will be undefined
.
console.log(food[food.length]); // undefined, as index is out of bound
Methods on an Array
The array has lots of methods that can make your life easier and increase your productivity. But there are some nuances that you need to take care of while using some of these methods. Iโll be working with the following list of fish.
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
length
- returns the number of elements in an arrayincludes
- takes an argument and returnstrue
ORfalse
depending on whether the element is in the array OR notindexOf
- returns the index of the first occurrence of a value in an array OR -1 if it is not presentpush
- it appends the element to the array and returns the new length of the arraypop
- removes the last element of the array and returns its valuejoin
- adds all the elements of an array into a string, separated by the specified separator string
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
// length
console.log(fruits.length); // 7
// includes
console.log(fruits.includes("๐")); // true
console.log(fruits.includes("โฝ๏ธ")); // false, element doesn't exists
// indexOf
console.log(fruits.indexOf("๐")); // 0
console.log(fruits.indexOf("๐ฅ")); // 6
console.log(fruits.indexOf("โฝ๏ธ")); // -1, element doesn't exists
// push
console.log(fruits.push("๐")); // 8
console.log(fruits); // ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ", "๐"]
// pop
console.log(fruits.pop()); // ๐
console.log(fruits); // ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"]
// join
console.log(fruits.join(" | ")); // "๐ | ๐ฅฅ | ๐ | ๐ | ๐ | ๐ | ๐ฅ"
find and findIndex
The find
method takes a function as an argument and returns the value of the first element in the array where the output of the passed function is true.
This is very useful for getting the first element that matches a certain condition. If the passed function never returns true
then the output will be undefined
indicating the element wasnโt found. This is what the find
method looks like:
// value of the current iteration
// ๐๐ฝ
arr.find((value, index) => {
// ๐๐ฝ
// index of the `value`
return true || false; // ๐๐ฝ if `true` then iteration will stop
});
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
// Checking if the fruits contain the following items
console.log(fruits.find((fruit, index) => fruit === "๐")); // ๐
console.log(fruits.find((fruit, index) => fruit === "โฝ๏ธ")); // undefined, doesn't exists
// Getting the 3rd element in the fruits list
console.log(fruits.find((fruit, index) => index === 3)); // ๐
The findIndex
method takes a function as an argument and returns the index of the first element in the array where the output of the passed function is true. This is what the findIndex
method looks like:
// value of the current iteration
// ๐๐ฝ
arr.findIndex((value, index) => {
// ๐๐ฝ
// index of the `value`
return true || false; // ๐๐ฝ if `true` then iteration will stop
});
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.findIndex((fruit, index) => fruit === "๐")); // 2
console.log(fruits.findIndex((fruit, index) => fruit === "โฝ๏ธ")); // -1, doesn't exists
fill, filter, forEach, and map (most important methods)
The fill
, filter
, forEach
, and map
are the most important methods of an array as they are used quite often.
The fill
method replaces the elements of an array from the given start
and end - 1
(as the end is exclusive) indexes with the value
that is passed to it. It looks something like this:
arr.fill(value, start, end);
// value - The value to fill the array with
// start - The start index
// end - The end index
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.fill("๐", 0, 3)); // [ "๐", "๐", "๐", "๐", "๐", "๐", "๐ฅ" ]
The filter
method loops through the array and returns a new array of filtered items. It takes a function as an argument which is applied to every item in the array. If it returned true
then it is appended to the final array (which is the result).
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
// Fruits whose index is even
console.log(fruits.filter((fruit, index) => index % 2 === 0));
// [ '๐', '๐', '๐', '๐ฅ' ]
// Fruits which are Apple
console.log(fruits.filter((fruit, index) => fruit === "๐"));
// [ '๐', '๐', '๐' ]
// Fruit doesn't exists
console.log(fruits.filter((fruit, index) => fruit === "โฝ๏ธ"));
// [], empty array
The forEach
method is a loop that can be used to operate with the array. It doesnโt return anything.
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
fruits.forEach((fruit, index) => {
console.log(fruit, index);
});
// Output:
// ๐ 0
// ๐ฅฅ 1
// ๐ 2
// ๐ 3
// ๐ 4
// ๐ 5
// ๐ฅ 6
The map
method is very useful as you can take the existing values in the array, transform them, and create a new array with the transformed values without affecting the original array. It takes a callback as an argument where the callback returns a value with which the final resultant array is created.
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(
fruits.map((fruit, index) => {
return `๐ ${fruit}`;
})
);
// Output - added ๐ emoji in front of the fruit emoji
// [ '๐ ๐', '๐ ๐ฅฅ', '๐ ๐', '๐ ๐', '๐ ๐', '๐ ๐', '๐ ๐ฅ' ]
slice, splice, shift, and unshift
The slice
method returns a copy of a section of an array. Negative indexes can also be used to for representing start and end. Note that start
can not be bigger than end
if not then the result will be an empty array ([]
). The end
argument is optional.
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.slice(2, 5)); // ["๐", "๐", "๐"]
console.log(fruits.slice(-1)); // ["๐ฅ"]
console.log(fruits.slice(-1, -4)); // [], -1 > -4 i.e. start > end, not a valid range
console.log(fruits.slice(2, -1)); // ["๐", "๐", "๐", "๐"]
The splice
method removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
arr.splice(start, deleteCount)
// start - start deleting elements from this index.
// If its >= arr.length then nothing is deleted resulting in empty arr
// deleteCount - delete this many items, if not specified then everything from `start` is deleted
let fruits = [];
// Removing items from index 2 till the end (as the delete count is not specified)
fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.splice(2)); // [ "๐", "๐", "๐", "๐", "๐ฅ" ]
console.log(fruits); // [ "๐", "๐ฅฅ" ]
// Deleting 3 items from index 2
fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.splice(2, 3)); // [ '๐', '๐', '๐' ]
console.log(fruits); // [ '๐', '๐ฅฅ', '๐', '๐ฅ' ]
// When start >= arr.length. Nothing is deleted
fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.splice(10, 3)); // []
console.log(fruits); // ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"]
The shift
method removes the first element from an array and returns it. If the array is empty, undefined is returned and the array is not modified. The unshift
method inserts new elements at the start of an array and returns the new length of the array.
Both shift
and unshift
methods perform some expensive computation since both of the methods shifts the elements of the array from the start.
// Shift method examples
fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.shift()); // ๐
console.log(fruits); // ["๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"]
console.log(fruits.shift()); // ๐ฅฅ
console.log(fruits); // ["๐", "๐", "๐", "๐", "๐ฅ]
// Unshift method examples
fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.unshift("๐ธ")); // 8, new length of the array
console.log(fruits); // ["๐ธ", "๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"]
concat, reverse, and sort
reverse
- it reverses the elements in an array in place. This method mutates the array and returns a reference to the same array.sort
- it sorts an array in place. This method mutates the array and returns a reference to the same array.concat
- it combines two or more arrays. This method returns a new array without modifying any existing arrays.
// Reverse example
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.reverse()); // ["๐ฅ", "๐", "๐", "๐", "๐", "๐ฅฅ", "๐"];
// Reverse example
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.sort()); // ["๐", "๐", "๐", "๐", "๐", "๐ฅ", "๐ฅฅ"];
// You can also pass a callback to the `sort` method to customize the sorting
// criteria
console.log(
fruits.sort(function (a, b) {
return a.length - b.length;
})
);
// ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
// Concat example
const fruits = ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ"];
console.log(fruits.concat(["๐", "๐", "๐"], ["๐", "๐", "๐"]));
// ["๐", "๐ฅฅ", "๐", "๐", "๐", "๐", "๐ฅ", "๐", "๐", "๐", "๐", "๐", "๐"];
Conclusion
Iโve covered the most important topics of Arrays in JavaScript along with mostly used methods in it. If you want to read more about the methods follow the MDN documentation.
If you liked this post then do ๐ like and give your ๐ feedback.