Chapter 3 · Data
Working with text
Step 1 of 22 · Concept
Every character has a number
By the end of this lesson you cut, compare and line up text.
- Each character has a number, its index, counted from 0:
word[0]is"H". word.at(-1)counts from the end:"o", the last character.word[10]is past the end. It givesundefined, not an error.
Step 2 of 22 · Quiz
Predict the characters
Type what this program prints.
const word = "Hello";
console.log(word[1], word.at(-1), word[10]);
Step 3 of 22 · Demo
See it run
Run it and compare with your answer. The last value is undefined, and the program goes on: no error.
Step 4 of 22 · Concept
slice cuts out a piece
word.slice(start, end) gives a new text: from start up to end, but not including end.
on "Hello" | gives |
|---|---|
word.slice(1, 4) | "ell" |
word.slice(2) | "llo": to the end |
word.slice(-3) | "llo": the last three |
word.slice(1, 99) | "ello": it stops at the end |
Step 5 of 22 · Demo
Pieces of a word
Run it. Then change -6 to -3 and run it again.
Step 6 of 22 · Exercise
Your turn: three pieces
From word, log its first three letters, then its last letter, then the word without its first letter. The program
must print:
Jav
t
avaScript
The end of slice is not included. The first three letters are at indexes 0, 1 and 2, so the end is 3: slice(0, 3), not slice(0, 2).
Three console.log lines: word.slice(0, 3), word.at(-1), and a slice with only a start.
console.log(word.slice(1));
Step 7 of 22 · Concept
Text never changes
let word = "Java";
word.toUpperCase();
word = word.toUpperCase();
A method such as toUpperCase() gives new text and leaves the old as it was. Line 2 alone changes nothing. Line 3
puts the new text in the box.
Step 8 of 22 · Concept
Methods on text
Each method gives a new value; word stays "banana".
on word, "banana" | gives |
|---|---|
word.toUpperCase(), word.toLowerCase() | "BANANA", "banana" |
" hi ".trim() | "hi": no spaces at the ends |
word.indexOf("an") | 1, where it first starts; -1 when absent |
word.includes("nan") | true |
word.startsWith("ba") | true |
word.replaceAll("a", "o") | "bonono"; replace changes only the first |
Step 9 of 22 · Quiz
Which value stayed the same?
Line 2 calls a method and keeps nothing. Type the missing line.
const word = " banana ".trim();
word.toUpperCase();
console.log(word);
console.log(word.toUpperCase());
console.log(word.indexOf("an"), word.indexOf("x"));
console.log(word.includes("nan"), word.startsWith("ba"));
Step 10 of 22 · Demo
See it run
Run it and compare with your answer. Then change line 2 to const big = word.toUpperCase(); and log big. Last,
add word[0] = "B"; at the end: Node stops with a TypeError.
Step 11 of 22 · Concept
Comparing text
=== compares two texts character by character. < compares the characters' codes: numbers the computer gives each
character. Capitals come before small letters, and digits before both.
| condition | gives | why |
|---|---|---|
"Ada" === "ada" | false | "A" and "a" differ |
"Z" < "a" | true | capitals come first |
"10" < "9" | true | "1" comes before "9" |
Step 12 of 22 · Concept
for...of walks through the characters
for (const ch of "Ada") {
console.log(ch);
}
for (const ch of word) runs its block once per character, in order. Each round, ch holds the next one: "A",
then "d", then "a".
Inside, test each character. ch >= "A" && ch <= "Z" is true for a capital: its code lies between those of
"A" and "Z".
Step 13 of 22 · Demo
Count the capitals
Run it. Then change the text to "JavaScript and Node" and run it again.
Step 14 of 22 · Exercise
Your turn: how many a's?
Count the letter a in text, capital or not. The program must print:
a: 5
"A" === "a" is false, so a test for "a" alone finds 3. Lower each character first: ch.toLowerCase().
A for (const ch of text) loop with an if inside: when the lowered ch is "a", add 1 to count.
if (ch.toLowerCase() === "a") {
Step 15 of 22 · Concept
split cuts, join glues
const parts = "red,green,blue".split(",");
console.log(parts[0], parts.length);
console.log(parts.join(", "));
split(",")cuts the text at each comma into an array:[ 'red', 'green', 'blue' ]. Lesson 10 says more.- The pieces have indexes and a
.length, as text has. This printsred 3. join(", ")glues them back into one text:red, green, blue.
text.split("\n") cuts input into lines. Input ends in \n, so the last piece is empty: .trim() the text first.
Step 16 of 22 · Quiz
How many lines?
The input is two lines, Ada and Alan, each ending in \n. What does this program print?
import { readFileSync } from "node:fs";
const text = readFileSync(0, "utf8");
const lines = text.split("\n");
console.log(lines.length, text.trim().split("\n").length);
Step 17 of 22 · Demo
See it run
The input is Ada and Alan, on two lines. Run it and compare with your answer. Then add
console.log(text.trim().split("\n").join(", ")); and run it again: Ada, Alan.
Step 18 of 22 · Concept
Lining up columns
| write | gives |
|---|---|
"ab".padEnd(5, ".") | "ab...": filled on the right to 5 |
"7".padStart(3, "0") | "007": filled on the left to 3 |
"2.50".padStart(6) | " 2.50": with spaces |
"-".repeat(14) | 14 dashes in a row |
Step 19 of 22 · Demo
A receipt that lines up
Run it: row pads a name and a price, so every line is 14 characters wide. Then change cake to 8 and run it again.
Step 20 of 22 · Check yourself
Check yourself: a proper name
The input is one line: ada lovelace. Turn it into a name card:
- Log the name with a capital at the start of each word:
Ada Lovelace. - Log a line of
=as long as that name. - Log the initials, each followed by a dot:
A.L..
The output must be:
Ada Lovelace
============
A.L.
Cut the input into its two words first. For each word, its first character as a capital, then the rest of it. The other two lines come from the name and those capitals.
Step 21 of 22 · Challenge · optional
Challenge: the dictionary's first word
Optional.
The input is two words on two lines: apple and Banana. Log the word a dictionary puts first. The output must be:
apple
< compares character codes, and capitals come first: "Banana" < "apple" is true, so < picks Banana.
a.localeCompare(b) compares as a dictionary does. It gives a negative number when a comes first, a positive one when b does.
if (words[0].localeCompare(words[1]) < 0) {
Step 22 of 22 · Recap
Recap
word[0]is the first character,word.at(-1)the last; past the end isundefined.slice(1, 4)cuts out a piece; the end is not included.- Text never changes: a method gives new text, and
word = word.toUpperCase()keeps it. splitcuts text into an array,joinglues it back;.trim()input beforesplit("\n").
Next: lesson 10 keeps many values in one array.
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 word = "Hello";
console.log(word[1], word.at(-1), word[10]);
const word = "JavaScript";
console.log(word.slice(0, 4));
console.log(word.slice(4));
console.log(word.slice(-6));
console.log(word.slice(1, 99));
const word = "JavaScript";
// log the first three letters, the last letter,
// then the word without its first letter
const word = " banana ".trim();
word.toUpperCase();
console.log(word);
console.log(word.toUpperCase());
console.log(word.indexOf("an"), word.indexOf("x"));
console.log(word.includes("nan"), word.startsWith("ba"));
let count = 0;
for (const ch of "Ada Lovelace") {
if (ch >= "A" && ch <= "Z") {
count++;
}
}
console.log("Capitals:", count);
const text = "Ada and Alan";
let count = 0;
// add 1 for each "a" or "A" in text
console.log("a:", count);
import { readFileSync } from "node:fs";
const text = readFileSync(0, "utf8");
const lines = text.split("\n");
console.log(lines.length, text.trim().split("\n").length);
function row(name, price) {
return name.padEnd(8, ".") + price.toFixed(2).padStart(6);
}
const tea = 2.5;
const cake = 12;
console.log(row("Tea", tea));
console.log(row("Cake", cake));
console.log("-".repeat(14));
console.log(row("Total", tea + cake));
import { readFileSync } from "node:fs";
const text = readFileSync(0, "utf8");
// 1. the name, each word with a capital
// 2. a line of = as long as the name
// 3. the initials: A.L.
import { readFileSync } from "node:fs";
const text = readFileSync(0, "utf8");
const words = text.trim().split("\n");
// log the word a dictionary puts first