Chapter 3 · Data
Arrays
Step 1 of 22 · Concept
An array keeps values in order
By the end of this lesson you keep, change and share lists of values.
const scores = [90, 75, 60];
- An array keeps values in order, between
[and]. - Index it as you index text (lesson 9):
scores[0]is90,scores.at(-1)is60,scores.lengthis3. scores[5]is past the end:undefined, not an error.- The array lives on the heap. The box holds an arrow to it.
Step 2 of 22 · Concept
How console.log shows a value
| you log | console.log shows |
|---|---|
"hi" | hi |
["hi"] | [ 'hi' ] |
[1, 2, 3] | [ 1, 2, 3 ] |
[] | [] |
[1, 2, 3, 4, 5, 6, 7] | four lines: the items in rows |
Text on its own shows bare. Inside an array, text shows in single quotes, with a space inside the brackets.
Step 3 of 22 · Quiz
Text or number?
What does this line print?
console.log(["7", 7, "Ada"]);
Step 4 of 22 · Concept
An array can change
| write | it does |
|---|---|
names.push("Grace") | adds "Grace" at the end |
names.pop() | removes the last item and gives it back |
names[0] = "Bo" | puts "Bo" in place of the first item |
names.shift(), names.unshift("Bo") | the same as pop and push, at the front |
Each one changes the array on the heap. The box names keeps its arrow to it.
Step 5 of 22 · Demo
Changes in a row
Run it. names is a const, and its array changes all the same: the part Two names, one array says why.
Step 6 of 22 · Concept
for...of walks through an array
for (const s of scores) gives s one item per round, in order, as it did with the characters of a text (lesson 9).
const scores = [90, 75, 60];
let total = 0;
for (const s of scores) {
total += s;
}
| ask | gives |
|---|---|
scores.includes(75) | true: it is there |
scores.indexOf(60) | 2: its index |
scores.indexOf(50) | -1: not there |
Step 7 of 22 · Demo
Scores in a loop
Run it. One loop adds up the scores and keeps the best one so far.
Step 8 of 22 · Concept
Stop early, skip a round
| write | it does |
|---|---|
break | ends the loop at once |
continue | skips the rest of this round and goes on with the next |
for (const n of [3, -1, 4, 0, 5]) {
if (n < 0) {
continue;
}
if (n === 0) {
break;
}
console.log(n);
}
This search logs the numbers up to the first 0, skipping the negative ones.
Step 9 of 22 · Demo
A loop that stops
Run it: -1 is skipped, and 0 ends the loop, so 5 is never reached.
Step 10 of 22 · Exercise
Your turn: the scores over 50
Put every score over 50 into the array high, with push in a loop. The program must print:
72, 90, 66
3 scores
50 is not over 50: compare with >, not >=, or 50 sneaks in and you get 4 scores.
A for...of over scores, with an if inside it. When the score is over 50, push it into high.
if (s > 50) {
high.push(s);
}
Step 11 of 22 · Concept
= does not copy an array
const a = [1, 2];
const b = a;
const c = [...a];
b.push(3);
const b = acopies the arrow, not the array: one array, two names.[...a]makes a new array with the same items: a copy.===compares arrows, not items:[1, 2] === [1, 2]isfalse.
Step 12 of 22 · Quiz
Which arrays changed?
Type the missing line.
const a = [1, 2];
const b = a;
const c = [...a];
b.push(3);
console.log(a);
console.log(c);
console.log(a === b, a === c);
Step 13 of 22 · Demo
See it run
Run it and compare with your answer. a is a const, yet its array changed: const fixes the box's arrow, not the
array. Then change line 3 to const c = a; and run it again.
Step 14 of 22 · Trace
A function changes your array
A call copies what is in the box into the parameter (lesson 7); here that is an arrow. The drawing leaves out the box
addBonus. Press Next to run one moment at a time.
function addBonus(list) {
list.push(5);
}
const scores = [70, 80];
addBonus(scores);
console.log(scores);- Lines 1 to 3 made the function
addBonus. Line 5 is next. - Line 5 made the array
[70, 80]; the boxscoresholds an arrow to it. Line 6 callsaddBonus(scores). - A frame for
addBonusis on the stack. Itslistgot a copy of the arrow: the same array. Line 2 is next. list.push(5)changed that one array: it is[70, 80, 5]. Line 3 ends the call.- The frame of
addBonusis gone.scoresstill points at the changed array. Line 7 is next. - Line 7 logged
[ 70, 80, 5 ]. The program is finished: the stack is empty, and no box points at the array.
Step 15 of 22 · Exercise
Your turn: a new array, the old one kept
Make doubled(xs) return a new array with each item of xs times 2, and leave xs as it is. The program must
print:
1, 2, 3
2, 4, 6
Pushing into xs while the loop walks it never ends: the array grows until Node stops with JavaScript heap out of memory. Push into a new array of your own.
Start with const result = [];. A for...of over xs pushes x * 2 into result; then return result;.
for (const x of xs) {
result.push(x * 2);
}
Step 16 of 22 · Demo
Two boxes from one pair
const [name, age] = pair; makes two boxes and fills them from the array, by position: item 0, then item 1.
[a, b] = [b, a] swaps two let boxes in one line. Run it.
Step 17 of 22 · Concept
Arrays inside an array
A grid is an array of rows: board[1][2] is row 1, then column 2. A loop inside a loop reaches every cell.
const board = [];
for (let r = 0; r < 3; r++) {
board.push([".", ".", "."]);
}
const trap = Array(3).fill([]);
trap[0].push("x");
Each round pushes a new row: three rows.
Step 18 of 22 · Quiz
One row or three?
Type the missing line.
const table = [];
for (let r = 1; r <= 3; r++) {
const row = [];
for (let c = 1; c <= 3; c++) {
row.push(r * c);
}
table.push(row);
}
for (const row of table) {
console.log(row.join(" "));
}
const trap = Array(3).fill([]);
trap[0].push("x");
console.log(trap);
Step 19 of 22 · Demo
A times table, and the trap
Run it and compare with your answer. A loop inside a loop fills every cell. Then change line 12 to
const trap = [[], [], []]; and run it again: three rows, and only the first gets the "x".
Step 20 of 22 · Check yourself
Check yourself: noughts and crosses
Build a noughts-and-crosses board and print it:
- Make
board: three rows of three".", a new row pushed each round of a loop. - Put
"X"at row 0, column 0, and"O"at row 1, column 1. - Log each row, its cells joined by a space.
The output must be:
X . .
. O .
. . .
Three parts in order: a loop that builds the rows, two lines that change one cell each (row first, then column), and a second loop that logs the rows.
Step 21 of 22 · Challenge · optional
Challenge: the board in a mirror
Optional.
Log each row, then |, then the row in a mirror. The board must stay as it was. The output must be:
X O . | . O X
. X O | O X .
O . . | . . O
First row: X O .
row.reverse() turns an array around in place: it changes the row itself, so the board changes too, and the last line says . O X.
Reverse a copy: [...row] makes one, and .reverse() turns the copy around. Then log both with a template literal.
const mirror = [...row].reverse();
Step 22 of 22 · Recap
Recap
- An array keeps values in order:
xs[0],xs.at(-1),xs.length. push,popandxs[i] = vchange it;for...ofwalks it, withbreakandcontinue.- The box holds an arrow:
const b = agives one array two names,[...a]makes a copy. - A function that pushes into its array argument changes the caller's array.
- A grid is an array of rows,
grid[r][c]: push a new row each round, neverfill([]).
Next: lesson 11 gives values names inside an object.
Review
3 questions from this lesson, in a new order each time. Answer from memory: 2 of 3 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
const names = ["Ada", "Alan"];
names.push("Grace");
console.log(names);
names[0] = "Bo";
const last = names.pop();
console.log(names, last);
console.log(names.length);
const scores = [90, 75, 60];
let total = 0;
let best = scores[0];
for (const s of scores) {
total += s;
if (s > best) {
best = s;
}
}
console.log("Total:", total);
console.log("Best:", best);
console.log("Average:", total / scores.length);
console.log(scores.includes(75), scores.indexOf(60));
for (const n of [3, -1, 4, 0, 5]) {
if (n < 0) {
continue;
}
if (n === 0) {
break;
}
console.log(n);
}
console.log("Done");
const scores = [72, 45, 90, 50, 38, 66];
const high = [];
// push each score over 50 into high
console.log(high.join(", "));
console.log(`${high.length} scores`);
const a = [1, 2];
const b = a;
const c = [...a];
b.push(3);
console.log(a);
console.log(c);
console.log(a === b, a === c);
function doubled(xs) {
// a new array: each item of xs times 2
return xs;
}
const nums = [1, 2, 3];
const twice = doubled(nums);
console.log(nums.join(", "));
console.log(twice.join(", "));
const pair = ["Ada", 36];
const [name, age] = pair;
console.log(name, age);
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b);
const table = [];
for (let r = 1; r <= 3; r++) {
const row = [];
for (let c = 1; c <= 3; c++) {
row.push(r * c);
}
table.push(row);
}
for (const row of table) {
console.log(row.join(" "));
}
const trap = Array(3).fill([]);
trap[0].push("x");
console.log(trap);
// 1. board: 3 rows of 3 ".", one push a round
// 2. "X" at row 0, col 0; "O" at row 1, col 1
// 3. log each row, joined by " "
const board = [
["X", "O", "."],
[".", "X", "O"],
["O", ".", "."],
];
for (const row of board) {
// log the row, " | ", then the row in a mirror
}
console.log("First row:", board[0].join(" "));