18.2 Arrays
If you want to store multiple values in one variable, you can do this with an array. You create an array by assigning comma-separated values to a variable in square brackets. This notation is also referred to as array literal notation. Let’s look at a simple example:
let user = ["John", "Frank", "Steven"];
This way, you can create an array with the identifier user and assign it three strings with user names. Surely, in this case, you could also use individual variables instead, as follows:
let user01 = "John";
var user02 = "Frank";
var user03 = "Steven";
In practice, using single variables is more complex and cumbersome than using an array. For example, what happens if you want to loop through multiple names to select a single name? And what do you do when you need 100 user names instead of 3? Here, you’re much better off with an array because you can manage many values with only one identifier.
If there are many entries in the array, it’s useful to write each entry in one line. This makes the array clearer. In practice, therefore, the following notation would be recommended:
let user = [
"John",
"Frank",
"Steven",
"Peter",
"Jay"
];
Unlike other programming languages, arrays in JavaScript can also contain entries with different data types. Thanks to loose typing, an array is also allowed as follows:
let user = [
"Wolfe",
46,
"email@email.com",
false
];
You can create an empty array as follows:
let user = []; // An empty array
Besides the array literal notation, you can also create an array using a constructor function via new:
let user = new Array(); // An empty array
You can also create an array with a specific size right away. For example, you create an array with 10 elements as follows:
let user = new Array(10); // 10 undefined elements
However, specifying the size of an array isn’t really necessary with arrays because an array can grow dynamically at runtime. Watch out when you create an array as follows:
let vals = new Array(10, 50); // 2 elements vals[0]:10, vals[1]:50
In that case, you create an array with two occupied elements. You can specify the length of the array only if you call the constructor function of Array() with a single decimal value as an argument.
Likewise, in the constructor function notation, you can already pass values directly as arguments:
let user = new Array("John", "Frank", "Steven");
For the arrays with Array(), you can also omit the keyword new. In practice, you’ll have to deal a lot with arrays in the future. Whether you prefer to use the array literal notation or the constructor function notation is up to you. I personally prefer the shorter array literal notation with the square brackets.
18.2.1 Accessing the Individual Elements in the Array
You can access the individual elements of an array using the square brackets and the corresponding index number. The first element in an array always has index [0], the second element index [1], and so on. For example:
let user = [
"John", // [0]
"Frank", // [1]
"Steven" // [2]
];
console.log(user[1]); // Output: Frank
let name01 = user[0]; // name01 = "John"
console.log(name01); // Output: John
user[2] = "Steve"; // "Steve" gets overwritten
console.log("user[0] = " + user[0]); // Output: user[0] = John
console.log("user[1] = " + user[1]); // Output: user[1] = Frank
console.log("user[2] = " + user[2]); // Output: user[2] = Steve
Listing 18.10 /examples/chapter018/18_2_1/script.js
Here’s a simple example of how to get the current day of the week by name using an array with all the days of the week, the Date object, and the getDay() method:
let date = new Date();
let day = date.getDay();
let wd = [
"Sunday", // wd[0]
"Monday", // wd[1]
"Tuesday", // wd[2]
"Wednesday", // wd[3]
"Thursday", // wd[4]
"Friday", // wd[5]
"Saturday" // wd[6]
];
console.log("Today is " + wd[day]);
Listing 18.11 /examples/chapter018/18_2_1/script2.js
You’ve already learned about the Date object and the getDay() method. In this example, you’ve added a wd array with all seven days of the week as individual strings. The order from Sunday with the value 0 to Saturday with the value 6 was kept just as the method getDay() returns a corresponding value from 0 to 6 of the day. If the example is executed on a Wednesday, the day variable is assigned the value 3 from date.getDay(), so using wd[day] in this case is equivalent to wd[3] and therefore uses the string "Wednesday" from the array.
18.2.2 Multidimensional Arrays
You can also use an array within another array, which is very useful, for example, if you need to manage data records that are always the same. You already know this principle from a spreadsheet. For example, the following data is given for a user administration:
let user = [
"pronix74", // Nickname
46, // Age
"wolfe@pronix.com", // Email
false // Administrator rights
];
Here, you have an array for a user, including nickname, age, email, and whether this user has admin rights. If you now want to create multiple users with the same data, you can do this using a multidimensional array as follows:
let user = [
["pronix74", // [0][0]
46, // [0][1]
"wolfe@pronix.com", // [0][2]
false // [0][3]
],
["halwa66", // [1][0]
51, // [1][1]
"halwa@pronix.com", // [1][2]
false // [1][3]
],
["woafu", // [2][0]
46, // [2][1]
"1@woafu.com", // [2][2]
true // [2][3]
]
];
Now you’ve created a multidimensional array with three users. The access works with the usual one-dimensional array over the index. With the first dimension, you specify the user as index (here, 0, 1, or 2), and with the second dimension, you access the desired value. For example, to access the data of the second user in the user array, you can do the following:
...
console.log(user[1][0]); // Output: halwa66
console.log(user[1][1]); // Output: 51
console.log(user[1][2]); // Output: halwa@pronix.com
console.log(user[1][3] ? "Admin" : "User"); // Output: User
Listing 18.12 /examples/chapter018/18_2/script.js
18.2.3 Adding or Removing New Elements in an Array
For adding and removing elements in an array, there are useful methods that make your life easier. Of course, it’s also possible to operate quite conventionally with the index operator on an array, but this also creates the risk that you produce undefined holes in the array. Here’s an example of the Spartan way:
let user = [
"John", // [0]
"Jason", // [1]
"Ben" // [2]
];
user[3] = "Tom";
user[5] = "Jay";
user[2] = undefined; // Delete value
for (let i = 0; i < user.length; i++) {
console.log(user[i]);
}
Listing 18.13 /examples/chapter018/18_2_3/script.js
In the example, holes were created for the elements user[2] and user[4]. The content of these elements is undefined. Of course, you can check in a loop where empty space exists (= undefined) and then insert the element there, but it’s much easier to keep the array without holes right away. In the example, the for loop pass also uses the length property, which contains the number of elements in an array.
Traversing Arrays Conveniently Using “for ... in” and “for ... of”
Instead of fiddling with the length property, however, you can use the for ... in or for ... of loop to run through the individual elements of an array. In the following example, you can see the for ... in loop in use, which outputs all elements from the user array:
let user = [
"John", // [0]
"Jason", // [1]
"Ben" // [2]
];
for (let n in user) {
console.log(user[n]);
}
The for ... of loop is a little more comfortable. It allows you to run only through the property values of the iterable properties and to omit a cumbersome user[n]. Here’s the same example again, but now with for ... of:
A Brief Overview of Common Methods for Adding and Removing Elements in the Array
For adding and removing elements, JavaScript provides specific methods. Table 18.1 contains a list of some common methods that are often used for this purpose.
|
Method |
Description |
|---|---|
|
pop() |
Removes the last element in the array |
|
push() |
Inserts a new element at the end of the array |
|
shift() |
Removes the first element of an array |
|
unshift() |
Inserts an element at the beginning of the array |
|
slice() |
Removes elements from an array |
|
splice() |
Adds, replaces, or deletes element(s) at any position in the array |
Table 18.1 Common Methods of Arrays
Adding and Removing Elements at the End: “push()” and “pop()”
To add elements at the end of the array, you can call the push() method, while the pop() method enables you to remove the last element. The argument you need to pass to the push() method is the element that is to be added, or you can pass several elements at once. The push() method returns the length of the array. Its counterpart pop(), on the other hand, doesn’t need an argument and always removes the last element in the array. As a return value, pop() returns the removed element or undefined if there’s no element left in the array. Here’s a simple example to demonstrate push() and pop() in use:
let user = []; // Empty array
user.push("pronix74");
user.push("halwa66");
console.log(user.length); // Output: 2
let size = user.push("root01", "scotty33", "anonymus");
console.log(size) // Output: 5
for (let n of user) {
console.log(n);
} // Output: pronix74, halwa66, root01, scotty33, anonymus
let n = user.pop(); // Remove last element -> anonymus
console.log(n + " was removed")
user.pop(); // Remove last element again
console.log(user.length); // Output: 3
for (let n of user) {
console.log(n);
} // Output: pronix74, halwa66, root01
Listing 18.14 /examples/chapter018/18_2_3/script2.js
Using an Array as a Stack
In programming, the push() and pop() methods are often used to use an array as a stack according to the last in, first out (LIFO) principle, which means that the last element placed on the stack with push()is always removed first with pop(). This can be used, for example, to implement the Undo function, which can be used to undo the last user action.
Adding and Remove Elements at the Beginning
The counterparts of push() and pop() are unshift() and shift() for adding and removing elements at the beginning of the array. The unshift() method works basically the same as push(), except that the element or elements are added at the beginning. This method also returns the new length of the array. The counterpart shift(), on the other hand, removes the first element in the array and returns it as a return value. Here’s a simple example to show these two methods in practice:
let user = []; // Empty array
user.unshift("pronix74");
user.unshift("halwa66");
console.log(user.length); // Output: 2
let size = user.unshift("root01", "scotty33", "anonymus");
console.log(size) // Output: 5
for (let n of user) {
console.log(n);
} // Output: root01, scotty33, anonymus, halwa66, pronix74
let n = user.shift(); // Remove first element -> root01
console.log(n + " was removed")
user.shift(); // Remove first element again
console.log(user.length); // Output: 3
for (let n of user) {
console.log(n);
} // Output: anonymus, halwa66, pronix74
Listing 18.15 /examples/chapter018/18_2_3/script3.js
Using an Array as a Queue
A queue is a data structure based on the first in, first out (FIFO) principle, where the first element in the queue is always returned, and new elements are added at the end. It’s the classic principle of a queue at the checkout. In practice, this data structure can be implemented by using the push() method to add the new elements at the end and the shift() method to return and remove the first element from the array. Of course, you can also write a queue the other way around, using pop() and unshift() instead of push() and shift(). A classical method for applying a queue are message queues, that is, queues for messages that are transmitted from the sender to a receiver.
Inserting and Removing Elements at Any Position in the Array: “splice()”
To add, remove, or replace elements from an array, you can use the splice() methods. The method allows for multiple arguments to be passed to it. The first argument is the relevant position where the new element should be added, removed, or replaced. As a second argument, you can specify the number of elements to be deleted from this position. If you want to only insert elements, you can use 0. The remaining arguments represent the elements you want to insert or replace in the array. The following example demonstrates all three options of splice() in use:
let user = [
"pronix74",
"halwa66",
"root01"
];
user.splice(2, 0, "anonymus"); // Insert at user[2].
for (let n of user) {
console.log(n);
} // Output: pronix74, halwa66, anonymus, root01
let del = user.splice(1, 2); // delete [1]&[2]
console.log(del + " were deleted!");
user.splice(1, 0, "woafu86", "john123"); // insert 2 elements
user.splice(0, 1, "pronix1974") // replace user[0] with pronix1974
for (let n of user) {
console.log(n);
} // Output: pronix74, woafu86, john123, root01
Listing 18.16 /examples/chapter018/18_2_3/script4.js
18.2.4 Sorting Arrays
The sort() method allows you to sort arrays. The advantage of this method is that you can use it to write your own function that sets the sorting criteria. You can define the comparison function with two parameters that are called internally in pairs for the values of the array when sort() is called. With an appropriate return of -1, 1, or 0, the sort() method then takes care of sorting the array. Return -1 if the value is greater than the second value. The opposite is true if you return 1. With a return value of 0, both values are equal.
The comparison function that sorts two strings (also works with numeric values) by their size (alphabet) looks as follows:
function compare(val1, val2) {
if (val1 < val2) {
return -1; // va1 is less than val2
} else if (val1 > val2) {
return 1; // val1 is greater than val2
} else {
return 0; // val1 and val2 are identical
}
}
“localCompare()”
I recommend that you use the localCompare() function for strings. This is part of the ECMAScript standard and compares the strings depending on the country-specific settings of the system.
A special feature in JavaScript is that you can pass this comparison function to the sort() method as an argument. This isn’t possible in all programming languages. I’ll get back to that momentarily. You can sort an array of strings alphabetically using the sort() method and the compare() function as follows:
...
let user = [
"halwa66",
"pronix74",
"conrad22",
"anton43",
"beta88"
];
user.sort(compare);
for (let n of user) {
console.log(n);
} // Output: anton43, beta88, conrad22, halwa66, pronix74
Because functions are also objects in JavaScript, they can be used as arguments or even return values just like variables, as you’ve seen with the sort(compare) function. With regard to the previous examples, you can also use this to implement the loop pass with the output of the individual elements as a function. For this, too, the arrays in JavaScript provide a useful and simple option: the forEach() method. The passed argument with this method gets output with each element. You can use it to output each element of an array via a function with forEach():
...
function printUser(item) {
console.log(item);
}
let user = [
"halwa66",
"pronix74",
"conrad22",
"anton43",
"beta88"
];
user.sort(compare);
user.forEach(printUser);
Listing 18.17 /examples/chapter018/18_2_4/script.js
18.2.5 Searching within Arrays
Before you write a function to search for a specific element in the array, let me introduce you to two functions for that as well. There’s nothing wrong with doing the following:
But for this purpose, JavaScript provides indexOf(), which enables you to search directly in the array for a specific element. You can specify the element to search for as an argument. Alternatively, you can use a second argument that determines from which index the search should be started. If -1 is returned, then the element isn’t contained in the array. For example:
console.log(user.indexOf("anton43"));
let pos = user.indexOf("hilary");
if (pos === -1) {
console.log("Could not find hilary!")
}
The indexOf() method starts searching at the beginning of the array. But if you want to start the search at the end of the array, you can use the lastIndexOf() method instead. The method is used in the same way as indexOf(). Other suitable methods such as find() and findIndex() should also be mentioned here. The find() method either returns the value of the element of an array that fulfills the condition of a provided test function, or it returns undefined. The findIndex() method either returns the index of the first element in the array that satisfies the provided test function, or it returns –1.
18.2.6 Additional Methods for Arrays
With the methods presented here, you should be very well equipped to get started with JavaScript for now. However, there are a lot of other methods available to you. I’ve listed some other useful methods in Table 18.2.
|
Method |
Description |
|---|---|
|
concat() |
Allows you to append elements or arrays to another array. |
|
copyWithin() |
Allows you to copy elements within the array. |
|
find() |
Allows you to search for elements according to search criteria. The search criteria are passed as an argument. The element which is found gets returned. |
|
Like find(), except that it returns the index of the first occurrence. |
|
|
filter() |
Allows you to sort out elements from the array according to certain filter criteria. Here, too, you pass the filter criteria in the form of a function as an argument. |
|
join() |
Converts an array into a string. |
|
reverse() |
Sorts the elements in the array into the reverse order. |
|
slice() |
Allows you to cut out individual elements from an array. |
|
toString() |
Enable you to convert arrays into strings. |
Table 18.2 Other Useful Methods to Work with Arrays