[toc]
Arrays are similar to strings, but are more general collection types. Like strings, arrays are a sequence of values that can be access via an ordered index. Unlike strings, arrays can store data of any type including other arrays.
The figure below demonstrates an array of named languages. The array contains four strings, each of those values has an index position. $$ \begin{aligned} \text{languages} & \rightarrow & \begin{array}{|c|c|} \hline 0 & \text{"Python"} \ \hline 1 & \text{"C#"} \ \hline 2 & \text{"Java"} \ \hline 3 & \text{"JavaScript"} \ \hline \end{array} \end{aligned} $$
Programmers have multiple ways to declare a new array. Array literal notation ([]) is the most simple. Anything enclosed in the square brackests will be items in the array. Each item should be separated by a comma (,). If there are no items inside the brackets, then the array is considered empty.
let emptyArray = [];
let languages = ["Python","C#","Java","JavaScript"];Arrays can also be declared on multiple lines.
let languages = [
"Python",
"C#",
"Java",
"JavaScript"
];To find the length of an aray, use the length property, just like with strings. JavaScript arry length is NOT fixed, meaning you can add or remove items dynamically.
let emptyArray = [];
console.log(emptyArray.length); // 0
let languages = ["Python","C#","Java","JavaScript"];
console.log(languages.length); // 4ℹ️ NOTE: In other languages, such as Java or C#, arrays are of static length requiring the length of an array to be declared upon creation. In JavaScript this is optional. Each cell will be filled with an
undefinedvalue until one is chosen.var four = new Array(4); // [undefined, undefined, undefined, undefined]; four.fill(0); // [0,0,0,0] four.fill("Bob"); // ["Bob","Bob","Bob","Bob"]
JavaScript arrays can hod a mixture of values of any type.
let grabBag = ["A String",true, 99, 105.7];ℹ️ NOTE: It's rare that you would store data of multiple tyes in the same array, beacause grouped data is usually the same data type. In other languages, like Java or C#, all items in the array have to be of the same type.
❓ Question: What is the lenght of the two arrays? (Hint: look closely at the quotes in the classes array).
let classes = ["science, computer, art"]; let teachers = ["Jones", "Willoughby", "Rhodes"];How can you change the
classesarray declaration to have the same number of items asthe teachersarray?❗Answer:
- One and three. The first one is not separated each comma.
- Insert quotes at the commas.
🤪 Their answer: "Yes, I have though of an answer, and I would like to check my thinking after I submit this quiz."
As previously discussed, arrays are an orderd collection where each item can be access via index. Similar to strings, an index in an array is the number order given to items. Individual items can be accessed using bracket notation. (array[index]). Indexes are zero-based going from 0 to array.length-1.
let languages = [
"Python", // index 0
"C#", // index 1
"Java", // index 2
"JavaScript" // index 3
];
console.log(languages[0]); // Python
console.log(languages[3]); // JavaScript
// What will happen when index 4 is requested?
console.log(languages[4]); // undefinedNotice that undefined was printed out when index 4 was referenced. undefined is returned when you request an index that the array does not contain.
ℹ️ NOTE:
undefinedis a special value in JavaScript that means no value has been assigned. We will discussundefinedin this class more later.
Example:
undefinedwill be returned for any index that is outside of the array's index range.let languages = ["Python","C#","Java","JavaScript"]; console.log(languges[-1]); // undefined console.log(languges[100]); // undefined
In programming, mutability refers to what happens when you attempt to change a value. Remember that ==strings are immutable==, meaning that any changes ot a string results in a new string being created. In contrast, ==arrays are mutable==, meaning that individual items in an array can be edited without a new array being created.
Example: Update an item in an array using bracket notation and index.
let frameworks = ["React", "Angular", "Ember"]; console.log(frameworks); // Set value of index 2 to be "Vue" frameworks[2] = "Vue"; // Notice the value at index 2 is now "Vue" console.log(frameworks);[ 'React', 'Angular', 'Ember' ] [ 'React', 'Angular', 'Vue' ]
As with strings, JavaScript provides us with useful methods for arrays. These methods will either alter an existing array, return information about the array, or create and return a new array.
ℹ️ NOTE: Much like I said in the previous chapter (namely in section 7.5.1) I'm not going to recreate the table here. There are way more methods than the table in the textbook has listed here. I will list the string methods in another document in my notes repository. In the mean time, take a look at
🤓 Actually... Also, they got their table wrong.
.splitis not part of theArrayclass. It's part of theStringclass and it suppost to be the complement ofArray's.joinmethod.
Use the information from the Array and String documentation to answer the following questions.
❓ Question: What is printed by the following code?
let charles = ['coder', 'Tech', 47, 23, 350]; charles.sort(); console.log(charles);a.
[350, 23, 47, 'Tech', 'coder']b.['coder', 'Tech', 23, 47, 350]c.[23, 47, 350, 'coder', 'Tech']d.[23, 350, 47, 'Tech', 'coder']❗ Answer: d. (Don't forget,
.sort()is case-sensitive!)
❓ Question: Which statement converts the string
str = 'LaunchCode students rock!'into the array['LaunchCode', 'students', 'rock!']? a.str.join(" ");b.str.split(" ");c.str.join("");d.str.split("");❗ Answer: b.
❓ Question: What is printed by the following program?
let groceryBag = ['bananas', 'apples', 'edamame', 'chips', 'cucumbers', 'milk', 'cheese']; let selectedItems = []; selectedItems = groceryBag.slice(2, 5).sort(); console.log(selectedItems);a.
['chips', 'cucumbers', 'edamame']b.['chips', 'cucumbers', 'edamame', 'milk']c.['cheese', 'chips', 'cucumbers']d.['cheese', 'chips', 'cucumbers', 'edamame']❗ Answer: a.
Earlier we learned that arrays can store any type of value. If that is true, can we store arrays inside of array? Yes!
A multi-dimensional array is an array of arrays, meaning that the values inside the array are also arrays. The inner arrays can store other values such as strings, numbers, or even other arrays.
This figure illustrates how it would look like. $$ \begin{aligned} \text{synonyms} & \rightarrow & \begin{array}{|c|c|c|c|} \hline & 0 & 1 & 2 \ \hline 0 & \text{"table"} & \text{"grid"} & \text{"spreadsheet"}\ \hline 1 & \text{"determined"} & \text{"serious"} & \text{"strong"} \ \hline 2 & \text{"potential"} & \text{"possible"} & \text{"likely"} \ \hline 3 & \text{"enhance"} & \text{"improve"} & \text{"upgrade"} \ \hline \end{array} \end{aligned} $$
The simplest form of a multi-dimensional array is a two dimensional array, or "matrix". A matrix is like a spreadsheet with rows and columns. To access items in a matrix, use square bracket notation and two indexes array[row][column]. The first index is for the outer array, or the "row". The second index is for the inner array, or "column".
ℹ️ NOTE: The row and column analogy is used to help visualize a two dimensional array, however it's not a perfect analogy. There are no specific JavaScript language rules forcing the inner arrays to all have the same length. The inner arrays are separate arrays that can be of different length.
Example: Use a two dimensional array to contain three different lists of space shuttle crews.
let shuttleCrews = [ ['Robert Gibson', 'Mark Lee', 'Mae Jemison'], ['Kent Rominger', 'Ellen Ochoa', 'Bernard Harris'], ['Eilen Collins', 'Winston Scott', 'Catherin Coleman'] ]; console.log(shuttleCrews[0][2]); // Mae Jemison console.log(shuttleCrews[1][1]); // Ellen Ochoa console.log(shuttleCrews[2][1]); // Winston Scott
In a matrix, both inner and outer arrays can be altered with array methods. However, bracket notation must be used correctly.
To apply a method to the outer array, the syntax is:
matrix.method();To apply a method to one of the inner arrays, the syntax is:
matrix[row].method();Example: Use array methods to add an addition crew array and alter existing arrays.
let shuttleCrews = [ ['Robert Gibson', 'Mark Lee', 'Mae Jemison'], ['Kent Rominger', 'Ellen Ochoa', 'Bernard Harris'], ['Eilen Collins', 'Winston Scott', 'Catherin Coleman'] ]; let newCrew = ['Mark Polansky', 'Robert Curbeam', 'Joan Higginbotham']; // Add a new crew array to the end of shuttleCrews shuttleCrews.push(newCrew); console.log(shuttleCrews[3][2]); // Reverse the order of the crew at index 1 shuttleCrews[1].reverse(); console.log(shuttleCrews[1]);Joan Higginbotham [ 'Bernard Harris', 'Ellen Ochoa', 'Kent Rominger' ]
Generally, there is no limit to how many dimensions you can have when creating arrays. However, it is rare that you will use more than two dimensions. Later on in this class, we will leanr about more collection types that can handle complex problems beyond the scope of two dimensional arrays.
❓ Question: What are the two dimensional indexes for
"Jones"?let school = [ ["science", "computer", "art"], ["Jones", "Willoughby", "Rhodes"] ];How would you add
"dance"to the end of the first array inschool[0]?How would you add
"Holmes"to the start of the second array inschool[1]?❗ Answer:
A.
school[1][0](Yes, this is the correct answer! I was right!)B.
school[0].push("dance");C.
school[1].unshift("Holmes");ℹ️ NOTE: I updated the questions on parts B and C since the questions were different.
❌ CENSORED
❌ CENSORED
Given the following array with a length of 4, here's how we would use .push, .pop, .unshift, and .shift:
$$
\begin{aligned}
\begin{array}{|c|c|c|}
\hline
0 & 1 & 2 & 3 \
\hline
\text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \
\hline
\end{array}
\end{aligned}
$$
A lot of books like to demonstrate these functions using the "plate stack" method. But Arrays in JavaScript are more like "queues" (Pronounced "Kewz") which are pretty much lines, like the one you would be in at the checkout at the supermarket.
let colors = ["orange","yellow","green","blue"];
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 4Push is pretty much like the person who just joined at the end of the line.
Push takes in the new item and puts it at the end. $$ \begin{aligned} \text{Before: } & & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \leftarrow \boxed{\text{"violet"}} \ \text{After: } & & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 & 4 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} & \text{"violet"} \ \hline \end{array} \end{aligned} $$ Push will return the new length of the array.
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 4
console.log(colors.push("violet")); // 5
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue', 'violet' ]
console.log(colors.length); // 5Pop can be though of as that one person who gets out of line at the end because they forgot something. $$ \begin{aligned} \text{Before: } & & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 & 4 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} & \text{"violet"} \ \hline \end{array} \ \text{After: } & & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \rightarrow \boxed{\text{"violet"}} \end{aligned} $$
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue', 'violet' ]
console.log(colors.length); // 5
console.log(colors.pop()); // 'violet'
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 4Unshift is like push, but it happens at the beginning of the queue. That person is the guy who butts in front of everybody else in the line.
Notice that the indices have all changed value! $$ \begin{aligned} \text{Before: } & & \boxed{\text{"red"}} \rightarrow \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \ \text{After: } & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 & 4 \ \hline \text{"red"} & \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \end{aligned} $$
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 4
console.log(colors.unshift("red")); // 5
console.log(colors); // [ 'red', 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 5Shift is like pop. You entered the line one way, and now you are leaving the other way. $$ \begin{aligned} \text{Before: } & & \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 & 4 \ \hline \text{"red"} & \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \ \text{After: } & & \boxed{\text{"red"}} \leftarrow \begin{array}{|c|c|c|} \hline 0 & 1 & 2 & 3 \ \hline \text{"orange"} & \text{"yellow"} & \text{"green"} & \text{"blue"} \ \hline \end{array} \end{aligned} $$
console.log(colors); // [ 'red', 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 5
console.log(colors.shift()); // 'red'
console.log(colors); // [ 'orange', 'yellow', 'green', 'blue' ]
console.log(colors.length); // 4const input = require('readline-sync');
let arr = [];
let len = 5;
console.log(`Give me ${len} numbers:`);
for(let i = 0; i < len; i++){
arr.push(Number(input.question(`(${i+1}/${len}): `)));
}
console.log("Great, now I'm just going to dump them out");
for(let i = 0; i < len; i++){ // You will be glad you DIDN'T use arr.length here!
console.log(arr.shift());
}There's another computer language called Bash that uses loops (which we will talk about in the next chapter), that reads a line of text, breaks it into an array, then reads each argument using a shift command, removing each argument from the beginning. This is sort of why when we pop an item off from the beginning we say "shift" rather than "unshift".
🎗️ TODO Finish this later. Also include
.spliceand.slice.
A string is pretty much an array of characters. But there's still some folks having some trouble how flexible this exchange between string and array type are. Let's take a string and break it apart. $$ \boxed{\text{"Jason"}} \implies \boxed{\begin{array}{c} 0 & 1 & 2 & 3 & 4 \ \hline \text{"J"} & \text{"a"} & \text{"s"} & \text{"o"} & \text{"n"} \end{array}} $$ Sure, that looks like how I described arrays. The top row indicates the index (position) of the character, and the bottom row is the corresponding character to that index.
A string has separators, if you count nothing as a separator. We'll show this shortly.
.split and .join need an argument inorder to work.
We disassemble a String into an Array using .split.
$$
\boxed{\begin{array}{c} 0 & 1 & 2 & 3 & 4 \
\hline
\text{"J"} & \text{"a"} & \text{"s"} & \text{"o"} & \text{"n"} \end{array}}
\xrightarrow{\text{split('')}}
\begin{array}{|c|}
\hline 0 & 1 & 2 & 3 & 4 \
\hline \text{"J"} & \text{"a"} & \text{"s"} & \text{"o"} & \text{"n"} \
\hline \end{array}
$$
let str = "Jason";
console.log(str); // 'Jason'
let arr = str.split('');
console.log(arr); // [ 'J', 'a', 's', 'o', 'n' ]We assemble an Array into a String using join.
$$
\begin{array}{|c|}
\hline 0 & 1 & 2 & 3 & 4 \
\hline \text{"J"} & \text{"a"} & \text{"s"} & \text{"o"} & \text{"n"} \
\hline \end{array}
\xrightarrow{\text{join('')}}
\boxed{\begin{array}{c} 0 & 1 & 2 & 3 & 4 \
\hline
\text{"J"} & \text{"a"} & \text{"s"} & \text{"o"} & \text{"n"} \end{array}}
$$
let arr = ["J","a","s","o","n"];
console.log(arr); // [ 'J', 'a', 's', 'o', 'n' ]
let str = arr.join('');
console.log(str); // 'Jason'Here's what happen when you don't use an argument in .split or .join
console.log("Jason".split()); // [ 'Jason' ]
console.log(["J","a","s","o","n"].join()); // 'J,a,s,o,n'🎗️ TODO: Here would be a good place to talk about Regular Expression.
console.log(["J","a","s","o","n"].reverse()); // [ 'n', 'o', 's', 'a', 'J' ]
console.log("Jason".reverse()); // ❌ TypeError: "Jason".reverse is not a functionBut there is a way around this!
console.log("Jason".split('').reverse().join('')); // 'nosaJ'🎗️ TODO See this.
str.concat(str2[, ...strN])
arr.concat(arr2[, ...arrN])
arr.concat(val1[, ...valN])str.slice( beginIndex[, endIndex] )
arr.slice([beginIndex[, endIndex]])Let's start with how .slice works in strings. Slice can have two arguments.
beginIndex- The zero-based index at which to begin extraction.- If omited,
beginIndexis treated as0. - If positive and less than
str.length, and noendIndexis defined, the new string will be from thebeginIndexposition to the end of the string. Basically it would be like sayingstr.slice(beginIndex,str.length-1). - If positive and greater than or equal to
str.length, and noendIndexis defined, the new string is an empty string,''. - If negative and the absolute value of
beginIndexis less thanstr.length, and noendIndexis defined, thebeginIndexisstr.length - beginIndex. So in a string that has a length of 5, ifbeginIndexis -1, it will be treated as if we had used 4 as thebeginIndex.
- If omited,
endIndex- (Optional) The zero-based index before which to end extraction. The characters at this index will not be included.- If omitted,
endIndexwill be treated asstr.length-1.
- If omitted,
Let's try it with string first.
let str = "Jason";
str.length; // 5
str.slice(); // 'Jason'
str.slice(0); // 'Jason'
str.slice(1); // 'ason'
str.slice(2); // 'son'
str.slice(3); // 'on'
str.slice(4); // 'n'
str.slice(5); // ''
str.slice(6); // ''
str.slice(-1); // 'n'
str.slice(-2); // 'on'
str.slice(-3); // 'son'
str.slice(-4); // 'ason'
str.slice(-5); // 'Jason'
str.slice(-6); // 'Jason'Let's make a table out of this to make it easier to visualize.
// TODO: Do a splice table later!
let str = "Jason";
const FS = '|'; // field (column) separator
const RS = '\n'; // record (row) separator
const PAD = ' '; // padding character
let tbl = ""; // Start with an empty table
//let row = ""; // with an empty row
// How row and column headers should look
function tblEdge(width,val){
return String(val).padStart(width,PAD);
}
// Table Header Row
function tblHeader(width,low,high){
let row = FS; // start each row with a pipe
row += PAD.repeat(width); // top-left corner cell
row += FS;
// Numbered row header with index in each cell
for(let i = low; i < high; i++){
row += tblEdge(width,i) + FS;
}
return row + RS;
}
console.log("rows represent beginIndex");
console.log("cols represent endIndex");
console.log();
//tbl += FS + "none".padStart(str.length,PAD);
tbl = tblHeader(str.length,-str.length-1,str.length+2);
//tbl = tbl.split('|').splice(2,0,"none".padStart(str.length,PAD)).join('|'); // splice is a destructive function! It returns removed elements. We can't do this like we did with reverse!;
// Insert position is 2 because there's a pipe at the beginning
// which makes tbl[0] = '' and tbl[1] = ' '.
tbl = tbl.split('|');
tbl.splice(2,0,"none".padStart(str.length,PAD));
tbl = tbl.join('|');
let out = "";
let row;
for(let i = -str.length -1; i <= str.length+1; i++){
row = FS + tblEdge(str.length,i) + FS; // Number our rows
// This row represent ommiting endIndex
row += str.slice(i).padStart(str.length,PAD) + FS;
for(let j = -str.length-1; j <= str.length+1; j++){
row += str.slice(i,j).padStart(str.length,PAD).padEnd(str.length,PAD) + FS;
}
tbl += row + RS;
}
console.log(tbl);🎗️ TODO: What's the difference between slice and substring?
str.substring(beginIndex[,endIndex])Substring can have two arguments
beginIndex- The index of the first character to include in the returned substring.endIndex(optional) - The index of the first character to exclude from the returned substring.
Substring will return a new string containing the specified part of the given string. It will extract chracters from beginIndex up to but not including endIndex.
- If there are no arguments, substring will return the string unchanged. (
"Jason".substring()will return"Jason".) But you probably don't intendt to use it like that. - If
endIndexis ommitted,substring()extracts characters to the end of the string. In other words, ifendIndexis not used,endIndexwill be set to the string length. - If
beginIndexis equal toendIndex, substring returns an empty string. This is pretty obvious from what we saw when we usedslice(). - if
beginIndexis greater thanendIndex, then the effects ofsubstring()are as if the two arguments were swapped. - Any argument that is less than zero or greater than the lenght of the string (
str.length), are treated as if they were zero or the length of the string respectively. - Any argument that is
NaNis treated as if it were0.
The difference between .slice and .substring are pretty clear. (See this link.)
🎗️ TODO
str = " Jason ";
str.trim();
str.trimStart();
str.trimEnd();
str = "Jason";
str.padStart();
str.padEnd();
// but no str.pad(); // 🎗TODO: Can there be?🏁 Woo! Eight chapters done. Up next: Repeating With Loops
#LaunchCode

