Skip to content

Latest commit

 

History

History
1902 lines (1290 loc) · 28.9 KB

06-Working with Strings.md

File metadata and controls

1902 lines (1290 loc) · 28.9 KB

Table of Contents

  • [[#Working With Strings Part 1|Working With Strings Part 1]]
    • [[#Working With Strings Part 1#Accessing Characters|Accessing Characters]]
    • [[#Working With Strings Part 1#String Length|String Length]]
    • [[#Working With Strings Part 1#Finding Position with .indexOf()|Finding Position with .indexOf()]]
    • [[#Working With Strings Part 1#Finding Last Position with .lastIndexOf()|Finding Last Position with .lastIndexOf()]]
    • [[#Working With Strings Part 1#Not Found: -1|Not Found: -1]]
  • [[#Slicing Strings|Slicing Strings]]
    • [[#Slicing Strings#Syntax|Syntax]]
    • [[#Slicing Strings#Slice from a Position|Slice from a Position]]
    • [[#Slicing Strings#Slice Between Two Positions|Slice Between Two Positions]]
    • [[#Slicing Strings#Extract First Word|Extract First Word]]
    • [[#Slicing Strings#Extract Last Word|Extract Last Word]]
  • [[#Negative Slice|Negative Slice]]
    • [[#Negative Slice#Slice with Negative End|Slice with Negative End]]
  • [[#Practical Example: Middle Seat Checker|Practical Example: Middle Seat Checker]] - [[#Slice with Negative End#Why slice(-1)?|Why slice(-1)?]]
  • [[#String Methods and Boxing|String Methods and Boxing]]
    • [[#String Methods and Boxing#new String()|new String()]]
    • [[#String Methods and Boxing#String Method Returns Primitive|String Method Returns Primitive]]
  • [[#Quick Summary|Quick Summary]]
  • [[#Core Syntax|Core Syntax]]
  • [[#Working With Strings Part 2|Working With Strings Part 2]]
    • [[#Working With Strings Part 2#Changing Case|Changing Case]]
  • [[#Fixing Capitalization|Fixing Capitalization]]
    • [[#Fixing Capitalization#How It Works|How It Works]]
  • [[#Comparing Emails|Comparing Emails]]
    • [[#Comparing Emails#Normalize Email|Normalize Email]]
    • [[#Comparing Emails#.trim()|.trim()]]
    • [[#Comparing Emails#Method Chaining|Method Chaining]]
  • [[#Replacing Text|Replacing Text]]
    • [[#Replacing Text#.replace()|.replace()]]
  • [[#Replacing First Match Only|Replacing First Match Only]]
  • [[#Replacing All Matches|Replacing All Matches]]
    • [[#Replacing All Matches#Option 1: replaceAll()|Option 1: replaceAll()]]
    • [[#Replacing All Matches#Option 2: Regular Expression|Option 2: Regular Expression]]
  • [[#Boolean String Methods|Boolean String Methods]]
    • [[#Boolean String Methods#.includes()|.includes()]]
    • [[#Boolean String Methods#.startsWith()|.startsWith()]]
    • [[#Boolean String Methods#.endsWith()|.endsWith()]]
    • [[#Boolean String Methods#Using Them in Conditions|Using Them in Conditions]]
  • [[#Case Sensitivity|Case Sensitivity]]
  • [[#Practice: Baggage Checker|Practice: Baggage Checker]]
    • [[#Practice: Baggage Checker#Why Convert to Lowercase?|Why Convert to Lowercase?]]
  • [[#Quick Syntax Summary|Quick Syntax Summary]]
  • [[#Method Summary|Method Summary]]
  • [[#Core Idea|Core Idea]]
  • [[#Working With Strings Part 3|Working With Strings Part 3]]
  • [[#split()|split()]]
    • [[#split()#Syntax|Syntax]]
    • [[#split()#Splitting by Space|Splitting by Space]]
  • [[#Destructuring After Split|Destructuring After Split]]
  • [[#join()|join()]]
    • [[#join()#Syntax|Syntax]]
  • [[#Capitalizing Full Names|Capitalizing Full Names]]
    • [[#Capitalizing Full Names#Code|Code]]
    • [[#Capitalizing Full Names#How It Works|How It Works]]
    • [[#Capitalizing Full Names#Alternative Using replace()|Alternative Using replace()]]
  • [[#Padding Strings|Padding Strings]]
    • [[#Padding Strings#padStart()|padStart()]]
    • [[#Padding Strings#padEnd()|padEnd()]]
  • [[#Practical Example: Mask Credit Card|Practical Example: Mask Credit Card]]
    • [[#Practical Example: Mask Credit Card#Code|Code]]
    • [[#Practical Example: Mask Credit Card#How It Works|How It Works]]
  • [[#repeat()|repeat()]]
    • [[#repeat()#Syntax|Syntax]]
  • [[#Practical Example: Planes in Line|Practical Example: Planes in Line]]
  • [[#Quick Syntax Summary|Quick Syntax Summary]]
  • [[#Method Summary|Method Summary]]
  • [[#Core Mental Model|Core Mental Model]]

Working With Strings Part 1

Strings are text values in JavaScript.

const airline = 'TAP Air Portugal';
const plane = 'A320';

Accessing Characters

Strings are indexed like arrays.

console.log(plane[0]); // A
console.log(plane[1]); // 3
console.log(plane[2]); // 2
console.log('B737'[0]); // B

Indexing starts from 0.

A 3 2 0
0 1 2 3

[!tip] Remember
The first character is always at index 0.


String Length

console.log(airline.length); // 16
console.log('B737'.length);  // 4

.length tells how many characters are in the string.

[!warning] Warning
Spaces also count as characters.

'TAP Air Portugal'

Has spaces after TAP and Air.


Finding Position with .indexOf()

console.log(airline.indexOf('r')); // 6

.indexOf() gives the index of the first matching character/text.

const airline = 'TAP Air Portugal';

airline.indexOf('r'); // 6

Finding Last Position with .lastIndexOf()

console.log(airline.lastIndexOf('r')); // 10

.lastIndexOf() gives the index of the last matching character/text.


Not Found: -1

console.log(airline.indexOf('portugal')); // -1

This returns -1 because strings are case-sensitive.

'Portugal' !== 'portugal'

[!warning] Warning
indexOf() returns -1 when the text is not found.


Slicing Strings

.slice() extracts part of a string.

Syntax

string.slice(startIndex, endIndex);

The endIndex is not included.


Slice from a Position

console.log(airline.slice(4)); 

Output:

Air Portugal

This starts from index 4 and goes to the end.


Slice Between Two Positions

console.log(airline.slice(4, 7));

Output:

Air

Indexes:

T A P   A i r   P o r t u g a l
0 1 2 3 4 5 6 7 8 9 10...

So:

slice(4, 7)

Means:

Start at 4
Stop before 7

[!important] Important
slice(4, 7) includes index 4, 5, 6, but not 7.


Extract First Word

console.log(airline.slice(0, airline.indexOf(' ')));

Output:

TAP

Explanation:

airline.indexOf(' ')

Finds the first space.

Then:

airline.slice(0, firstSpace)

Extracts everything before the first space.


Extract Last Word

console.log(airline.slice(airline.lastIndexOf(' ') + 1));

Output:

Portugal

Explanation:

airline.lastIndexOf(' ')

Finds the last space. Then adds 1 to the index of the last space essentially taking the index value to that of P in this case, and since no endIndex is provided it will continue till the string ends.

[!tip] Pattern
To get the last word:

string.slice(string.lastIndexOf(' ') + 1);

Negative Slice

Negative indexes count from the end.

console.log(airline.slice(-2));

Output:

al

This gets the last 2 characters.


Slice with Negative End

console.log(airline.slice(1, -1));

Output:

AP Air Portuga

Explanation:

slice(1, -1)

Means:

Start from index 1
Stop before the last character

Practical Example: Middle Seat Checker

In airplanes, seats ending with B or E are usually middle seats.

const checkMiddleSeat = function (seat) {
  const s = seat.slice(-1);

  if (s === 'B' || s === 'E') {
    console.log('You got the middle seat 😐');
  } else {
    console.log('You got lucky 😎');
  }
};

Usage:

checkMiddleSeat('11B'); // You got the middle seat 😐
checkMiddleSeat('23C'); // You got lucky 😎
checkMiddleSeat('3E');  // You got the middle seat 😐

Why slice(-1)?

const s = seat.slice(-1);

This gets the last character of the seat string.

'11B'.slice(-1); // B
'23C'.slice(-1); // C
'3E'.slice(-1);  // E

[!tip] Useful Trick
To get the last character of a string:

string.slice(-1);

String Methods and Boxing

Strings are primitive values.

const name = 'Jonas';

But we can still use methods on them:

name.slice(1);
name.indexOf('o');
name.length;

This works because JavaScript temporarily converts the primitive string into a String object.

This process is called boxing.


new String()

console.log(new String('Jonas'));

Output:

String {'Jonas'}

This creates a String object.

console.log(typeof new String('Jonas'));

Output:

object

[!warning] Warning
Usually, do not create strings using new String().

Prefer this:

const name = 'Jonas';

Not this:

const name = new String('Jonas');

String Method Returns Primitive

console.log(typeof new String('Jonas').slice(1));

Output:

string

Even though new String('Jonas') is an object, .slice() returns a normal primitive string.


Quick Summary

Concept fMeaning
str[index] Gets character at index
str.length Number of characters
str.indexOf(value) First position
str.lastIndexOf(value) Last position
str.slice(start) Extract from start to end
str.slice(start, end) Extract from start to before end
str.slice(-1) Last character
indexOf() returns -1 Value not found

Core Syntax

const airline = 'TAP Air Portugal';

airline[0];                 // T
airline.length;             // 16
airline.indexOf('r');       // 6
airline.lastIndexOf('r');   // 10

airline.slice(4);           // Air Portugal
airline.slice(4, 7);        // Air
airline.slice(-2);          // al
airline.slice(1, -1);       // AP Air Portuga

Main idea: strings can be read by position, searched with indexOf(), and cut into smaller parts with slice().


Working With Strings Part 2

String methods help us change, clean, search, and check text.

const airline = 'TAP Air Portugal';

Changing Case

airline.toLowerCase();
airline.toUpperCase();

Example:

console.log(airline.toLowerCase()); // tap air portugal
console.log(airline.toUpperCase()); // TAP AIR PORTUGAL
Method Meaning
toLowerCase() Converts string to lowercase
toUpperCase() Converts string to uppercase

[!important] Important
These methods return a new string. They do not permanently change the original string.


Fixing Capitalization

Suppose we have:

const passenger = 'jOnAS';

We want:

Jonas

Steps:

const passengerLower = passenger.toLowerCase();

const passengerCorrect =
  passengerLower[0].toUpperCase() + passengerLower.slice(1);

console.log(passengerCorrect); // Jonas

How It Works

passenger.toLowerCase();

Gives:

jonas

Then:

passengerLower[0].toUpperCase()

Gives:

J

And:

passengerLower.slice(1)

Gives:

onas

Final result:

J + onas = Jonas

[!tip] Pattern
To capitalize the first letter:

str[0].toUpperCase() + str.slice(1);

Comparing Emails

User input often has extra spaces or wrong capitalization.

const email = 'hello@jonas.io';
const loginEmail = '  Hello@Jonas.Io \n';

This is not directly equal because:

'hello@jonas.io' !== '  Hello@Jonas.Io \n'

Normalize Email

const normalizedEmail = loginEmail.toLowerCase().trim();

console.log(normalizedEmail); // hello@jonas.io
console.log(email === normalizedEmail); // true

.trim()

str.trim();

Removes extra whitespace from the beginning and end.

Whitespace includes:

spaces
tabs
new lines \n

Example:

'  hello \n'.trim(); // hello

[!tip] Tip
Use .trim() when cleaning user input.


Method Chaining

loginEmail.toLowerCase().trim();

This is called method chaining.

It works like this:

loginEmail.toLowerCase()

returns a new string, then .trim() runs on that new string.

[!info] Chain Rule
You can chain methods when each method returns a value that can be used by the next method.


Replacing Text

const priceGB = '288,97£';

Convert it to US format:

const priceUS = priceGB.replace('£', '$').replace(',', '.');

console.log(priceUS); // 288.97$

.replace()

Syntax:

str.replace(oldValue, newValue);

Example:

'288,97£'.replace('£', '$');

Result:

288,97$

[!warning] Warning
.replace() replaces only the first match by default.


Replacing First Match Only

const announcement =
  'All passengers come to boarding door 23. Boarding door 23!';

console.log(announcement.replace('door', 'gate'));

Output:

All passengers come to boarding gate 23. Boarding door 23!

Only the first door changed.


Replacing All Matches

Option 1: replaceAll()

announcement.replaceAll('door', 'gate');

Option 2: Regular Expression

announcement.replace(/door/g, 'gate');

Output:

All passengers come to boarding gate 23. Boarding gate 23!

[!important] Important
/door/g means: find all occurrences of "door".

g = global

Boolean String Methods

These methods return either:

true
false

.includes()

Checks whether a string contains some text.

const plane = 'Airbus A320neo';

console.log(plane.includes('A320'));   // true
console.log(plane.includes('Boeing')); // false

Syntax:

str.includes(searchText);

.startsWith()

Checks whether a string starts with specific text.

console.log(plane.startsWith('Airb')); // true

Syntax:

str.startsWith(searchText);

.endsWith()

Checks whether a string ends with specific text.

console.log(plane.endsWith('neo')); // true

Syntax:

str.endsWith(searchText);

Using Them in Conditions

if (plane.startsWith('Airbus') && plane.endsWith('neo')) {
  console.log('Part of the NEW Airbus family');
}

This means:

Starts with Airbus
AND
Ends with neo

[!tip] Use Case
These methods are useful for validation and checking user input.


Case Sensitivity

String methods are case-sensitive.

'Airbus A320neo'.includes('airbus'); // false
'Airbus A320neo'.includes('Airbus'); // true

To avoid case problems:

str.toLowerCase().includes('airbus');

Practice: Baggage Checker

Goal: block passengers if their baggage contains knife or gun.

const checkBaggage = function (items) {
  const baggage = items.toLowerCase();

  if (baggage.includes('knife') || baggage.includes('gun')) {
    console.log('You are NOT allowed on board');
  } else {
    console.log('Welcome aboard!');
  }
};

Usage:

checkBaggage('I have a laptop, some Food and a pocket Knife');
// You are NOT allowed on board

checkBaggage('Socks and camera');
// Welcome aboard!

checkBaggage('Got some snacks and a gun for protection');
// You are NOT allowed on board

Why Convert to Lowercase?

const baggage = items.toLowerCase();

Because user input may have different capitalization:

Knife
KNIFE
knife

After .toLowerCase():

knife
knife
knife

Now checking becomes easy:

baggage.includes('knife')

[!warning] Warning
Without .toLowerCase(), this may fail:

'Pocket Knife'.includes('knife'); // false

Because Knife and knife are different.


Quick Syntax Summary

str.toLowerCase();
str.toUpperCase();

str.trim();

str.replace(oldValue, newValue);
str.replaceAll(oldValue, newValue);
str.replace(/oldValue/g, newValue);

str.includes(searchText);
str.startsWith(searchText);
str.endsWith(searchText);

Method Summary

Method Returns Meaning
toLowerCase() String Converts to lowercase
toUpperCase() String Converts to uppercase
trim() String Removes outer whitespace
replace() String Replaces first match
replaceAll() String Replaces all matches
includes() Boolean Checks if text exists
startsWith() Boolean Checks starting text
endsWith() Boolean Checks ending text

Core Idea

String methods help you clean and check text.

Most common pattern:

const cleaned = userInput.toLowerCase().trim();

Then check it:

cleaned.includes('some text');

[!success] Remember
For user input, always think:
clean first, then compare.


Working With Strings Part 3

Main idea:
This part focuses on converting strings to arrays, arrays back to strings, padding strings, masking data, and repeating strings.


split()

split() breaks a string into an array.

Syntax

string.split(separator);

Example:

console.log('a+very+nice+string'.split('+'));

Output:

['a', 'very', 'nice', 'string']

The + is used as the cutting point.


Splitting by Space

console.log('Jonas Schmedtmann'.split(' '));

Output:

['Jonas', 'Schmedtmann']

[!tip] Tip
Use .split(' ') when you want to separate words.


Destructuring After Split

const [firstName, lastName] = 'Jonas Schmedtmann'.split(' ');

This means:

firstName → Jonas
lastName  → Schmedtmann

Because:

'Jonas Schmedtmann'.split(' ')

returns:

['Jonas', 'Schmedtmann']

join()

join() combines array elements into a string.

Syntax

array.join(separator);

Example:

const newName = ['Mr.', firstName, lastName.toUpperCase()].join(' ');

console.log(newName);

Output:

Mr. Jonas SCHMEDTMANN

[!important] Important
split() does this:

String → Array

join() does this:

Array → String

Capitalizing Full Names

Goal:

jessica ann smith davis

Convert to:

Jessica Ann Smith Davis

Code

const capitalizeName = function (name) {
  const names = name.split(' ');
  const namesUpper = [];

  for (const n of names) {
    namesUpper.push(n[0].toUpperCase() + n.slice(1));
  }

  console.log(namesUpper.join(' '));
};

capitalizeName('jessica ann smith davis');
capitalizeName('jonas schmedtmann');

Output:

Jessica Ann Smith Davis
Jonas Schmedtmann

How It Works

const names = name.split(' ');

Turns this:

'jessica ann smith davis'

Into this:

['jessica', 'ann', 'smith', 'davis']

Then each word is capitalized:

n[0].toUpperCase() + n.slice(1)

Example:

'jessica'

Becomes:

'J' + 'essica'

Final result:

'Jessica'

[!tip] Capitalization Pattern
To capitalize one word:

word[0].toUpperCase() + word.slice(1);

Alternative Using replace()

namesUpper.push(n.replace(n[0], n[0].toUpperCase()));

This replaces the first letter with its uppercase version.

'jonas'.replace('j', 'J'); // Jonas

[!warning] Warning
This works here because we are replacing the first character.
For learning, this version is usually clearer:

n[0].toUpperCase() + n.slice(1)

Padding Strings

Padding means adding characters to a string until it reaches a certain length.


padStart()

Adds characters at the beginning.

string.padStart(targetLength, paddingText);

Example:

const message = 'Go to gate 23!';

console.log(message.padStart(20, '+'));

Output:

++++++Go to gate 23!

padEnd()

Adds characters at the end.

string.padEnd(targetLength, paddingText);

Example:

console.log(message.padStart(20, '+').padEnd(30, '+'));

Output:

++++++Go to gate 23!++++++++++

[!important] Important
targetLength means the final total length, not how many characters to add.

'Jonas'.padStart(10, '+');

Output:

+++++Jonas

The final length is 10.


Practical Example: Mask Credit Card

Goal:

64637836

Convert to:

****7836

Code

const maskCreditCard = function (number) {
  const str = number + '';
  const last = str.slice(-4);

  return last.padStart(str.length, '*');
};

console.log(maskCreditCard(64637836));
console.log(maskCreditCard(43378463864647384));
console.log(maskCreditCard('334859493847755774747'));

Output:

****7836
*************7384
*****************4747

How It Works

const str = number + '';

Converts the number into a string.

64637836 + ''

Becomes:

'64637836'

Then:

const last = str.slice(-4);

Gets the last 4 characters.

'64637836'.slice(-4); // 7836

Finally:

last.padStart(str.length, '*');

Pads the last 4 digits until the full original length is reached.

[!tip] Useful Pattern
To hide everything except the last 4 characters:

str.slice(-4).padStart(str.length, '*');

repeat()

repeat() repeats a string multiple times.

Syntax

string.repeat(numberOfTimes);

Example:

const message2 = 'Bad weather... All Departures Delayed... ';

console.log(message2.repeat(5));

Output:

Bad weather... All Departures Delayed... Bad weather... All Departures Delayed... Bad weather... All Departures Delayed... Bad weather... All Departures Delayed... Bad weather... All Departures Delayed...

Practical Example: Planes in Line

const planesInLine = function (n) {
  console.log(`There are ${n} planes in line ${'🛩'.repeat(n)}`);
};

planesInLine(5);
planesInLine(3);
planesInLine(12);

Output:

There are 5 planes in line 🛩🛩🛩🛩🛩
There are 3 planes in line 🛩🛩🛩
There are 12 planes in line 🛩🛩🛩🛩🛩🛩🛩🛩🛩🛩🛩🛩

[!warning] Warning
repeat() needs a non-negative number.

'Hi'.repeat(3);  // HiHiHi
'Hi'.repeat(0);  // ''
'Hi'.repeat(-1); // error

Quick Syntax Summary

str.split(separator);

array.join(separator);

str.padStart(targetLength, paddingText);
str.padEnd(targetLength, paddingText);

str.repeat(times);

Method Summary

Method Returns Meaning
split() Array Breaks string into parts
join() String Joins array into string
padStart() String Adds padding at start
padEnd() String Adds padding at end
repeat() String Repeats string

Core Mental Model

String transformations often follow this pattern:

Split → Modify → Join

Example:

const words = name.split(' ');
const fixedWords = [];
fixedWords.push(...);
const finalName = fixedWords.join(' ');

Most important idea:
String methods do not change the original string. They return a new string.


String Methods Practice

Goal:
Convert messy flight data into clean, readable flight messages.


Raw Flight Data

const flights =
  '_Delayed_Departure;fao93766109;txl2133758440;11:25+_Arrival;bru0943384722;fao93766109;11:45+_Delayed_Arrival;hel7439299980;fao93766109;12:05+_Departure;fao93766109;lis2323639855;12:30';

The data is stored as one long string.

Each flight is separated by:

+

Each piece of flight information is separated by:

;

Data Structure

One flight looks like this:

_Delayed_Departure;fao93766109;txl2133758440;11:25

It contains:

type;from;to;time

Meaning:

_Delayed_Departure → flight type
fao93766109        → from airport
txl2133758440      → to airport
11:25              → time

Step 1: Split Flights

flights.split('+')

This converts the big string into an array of individual flights.

[
  '_Delayed_Departure;fao93766109;txl2133758440;11:25',
  '_Arrival;bru0943384722;fao93766109;11:45',
  '_Delayed_Arrival;hel7439299980;fao93766109;12:05',
  '_Departure;fao93766109;lis2323639855;12:30'
]

[!tip] Remember
split() converts a string into an array.


Step 2: Loop Over Each Flight

for (const flight of flights.split('+')) {
  console.log(flight);
}

This loops through each flight one by one.


Step 3: Split Flight Details

const [type, from, to, time] = flight.split(';');

Example:

'_Delayed_Departure;fao93766109;txl2133758440;11:25'.split(';')

Gives:

[
  '_Delayed_Departure',
  'fao93766109',
  'txl2133758440',
  '11:25'
]

Using destructuring:

type → '_Delayed_Departure'
from → 'fao93766109'
to   → 'txl2133758440'
time → '11:25'

[!important] Key Idea
split(';') breaks the flight into useful parts.


Step 4: Get Airport Code

Airport strings are messy:

fao93766109
txl2133758440

We only want the first 3 letters:

FAO
TXL

Helper Function

const getCode = str => str.slice(0, 3).toUpperCase();

How it works:

'fao93766109'.slice(0, 3);      // fao
'fao93766109'.slice(0, 3).toUpperCase(); // FAO

[!tip] Pattern
Use helper functions when the same logic is repeated.


Step 5: Check If Flight Is Delayed

type.startsWith('_Delayed')

Examples:

'_Delayed_Departure'.startsWith('_Delayed'); // true
'_Arrival'.startsWith('_Delayed');           // false

If delayed, show:

🔴

Using ternary operator:

type.startsWith('_Delayed') ? '🔴' : ''

Meaning:

if delayed → '🔴'
else       → ''

Step 6: Clean Flight Type

The type has underscores:

_Delayed_Departure

We want:

 Delayed Departure

Use:

type.replaceAll('_', ' ')

Example:

'_Delayed_Departure'.replaceAll('_', ' ');

Output:

 Delayed Departure

[!info] Note
The first underscore also becomes a space, so the result starts with a space.


Alternative for Older Syntax

type.replace(/_/g, ' ')

Here:

g

means global, or replace all matches.


Step 7: Format Time

Original time:

11:25

Required format:

11h25

Use:

time.replace(':', 'h')

Example:

'11:25'.replace(':', 'h'); // 11h25

Step 8: Align Output with padStart()

output.padStart(36)

This adds spaces at the beginning until the string length becomes 36.

It helps align the output nicely:

     🔴 Delayed Departure from FAO to TXL (11h25)
              Arrival from BRU to FAO (11h45)

[!important] Important
padStart(36) means final length should be 36, not add 36 spaces.


Final Code

const flights =
  '_Delayed_Departure;fao93766109;txl2133758440;11:25+_Arrival;bru0943384722;fao93766109;11:45+_Delayed_Arrival;hel7439299980;fao93766109;12:05+_Departure;fao93766109;lis2323639855;12:30';

const getCode = str => str.slice(0, 3).toUpperCase();

for (const flight of flights.split('+')) {
  const [type, from, to, time] = flight.split(';');

  const output = `${type.startsWith('_Delayed') ? '🔴' : ''}${type.replaceAll(
    '_',
    ' '
  )} from ${getCode(from)} to ${getCode(to)} (${time.replace(
    ':',
    'h'
  )})`.padStart(36);

  console.log(output);
}

[!warning] Warning
In your reference code, from and to words are missing from the template string.
Without them, output becomes like Departure FAO LIS, not Departure from FAO to LIS.


Expected Output

 🔴 Delayed Departure from FAO to TXL (11h25)
              Arrival from BRU to FAO (11h45)
   🔴 Delayed Arrival from HEL to FAO (12h05)
            Departure from FAO to LIS (12h30)

Full Flow

big string
   ↓ split('+')
array of flights
   ↓ loop
single flight string
   ↓ split(';')
type, from, to, time
   ↓ clean each part
formatted flight message
   ↓ padStart()
aligned output

Methods Used

Method Purpose
split('+') Separate each flight
split(';') Separate flight details
slice(0, 3) Get airport code
toUpperCase() Convert airport code to uppercase
startsWith() Check if delayed
replaceAll('_', ' ') Clean flight type
replace(':', 'h') Format time
padStart(36) Align output

Core Syntax

str.split(separator);

str.slice(start, end);

str.toUpperCase();

str.startsWith(searchText);

str.replace(oldValue, newValue);

str.replaceAll(oldValue, newValue);

str.padStart(targetLength);

Core Idea

This exercise is about cleaning messy string data.

The main pattern is:

Split → Destructure → Clean → Format → Align

[!success] Remember
Real-world data is often messy. String methods help convert it into readable, useful output.