JavaScript · Syntax · Beginner
OOP, objects, algorithmic thinking
JavaScript exercises on OOP, objects, and algorithmic thinking: classes for data analysis, word and character counting, working with ratings, passwords, statistics, and object transformations.
Quick topic start and explanations before exercises (exercises below):
Registry, counter, and aggregator patterns
#Exercises:
WordCounter for text.
#Create a WordCounter class that takes a text string. Add a count method that returns an object where: - the key is a word - the value is how many times it appears in the text
class WordCounter {
// your code here
}
Solution
class WordCounter {
constructor(text) {
this.text = text;
}
count() {
let result = {};
let words = this.text.trim()
? this.text.trim().split(/\s+/)
: [];
for (let w of words) {
if (w in result) {
result[w] += 1;
} else {
result[w] = 1;
}
}
return result;
}
}
GradeBook journal.
#Create a GradeBook class. The add(name, grade) method adds a grade for a student. The average(name) method returns the student's average grade.
class GradeBook {
// your code here
}
Solution
class GradeBook {
constructor() {
this.data = {};
}
add(name, grade) {
if (!(name in this.data)) {
this.data[name] = [];
}
this.data[name].push(grade);
}
average(name) {
let grades = this.data[name] ?? [];
if (grades.length === 0) {
return 0;
}
return grades.reduce((total, value) => total + value, 0) / grades.length;
}
}
Counting each letter.
#Write a function that takes a string and returns an object with the count of each letter.
function letterStats(text) {
// your code here
}
Solution
function letterStats(text) {
let result = {};
for (let ch of text) {
if (/^\p{L}$/u.test(ch)) {
ch = ch.toLowerCase();
if (ch in result) {
result[ch] += 1;
} else {
result[ch] = 1;
}
}
}
return result;
}
Password strength check.
#Create a PasswordChecker class. The check method returns true if the password: - length ≥ 8 - contains at least one digit
class PasswordChecker {
// your code here
}
Solution
class PasswordChecker {
check(password) {
if (password.length < 8) {
return false;
}
let hasDigit = false;
for (let ch of password) {
if (/^\d$/.test(ch)) {
hasDigit = true;
break;
}
}
return hasDigit;
}
}
Inventory of items.
#Create an Inventory class. The addItem(name, count) method adds an item. The totalItems() method returns the total quantity of all items.
class Inventory {
// your code here
}
Solution
class Inventory {
constructor() {
this.items = {};
}
addItem(name, count) {
if (name in this.items) {
this.items[name] += count;
} else {
this.items[name] = count;
}
}
totalItems() {
let total = 0;
for (let c of Object.values(this.items)) {
total += c;
}
return total;
}
}
Grouping words by length.
#Write a function that takes an array of words and returns an object: - the key is the word length - the value is how many words have that length
function lengthGroups(words) {
// your code here
}
Solution
function lengthGroups(words) {
let result = {};
for (let w of words) {
let l = w.length;
if (l in result) {
result[l] += 1;
} else {
result[l] = 1;
}
}
return result;
}
BankAccount without going negative.
#Create a BankAccount class with methods: - deposit(amount) - withdraw(amount) — does not allow the balance to go negative
class BankAccount {
// your code here
}
Solution
class BankAccount {
constructor(balance) {
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
return true;
}
return false;
}
}
Vowels and consonants.
#Write a function that takes a string and returns an object with the number of vowels and consonants.
function vowelsAndConsonants(text) {
// your code here
}
Solution
function vowelsAndConsonants(text) {
let vowels = "aeiou";
let result = {
vowels: 0,
consonants: 0
};
for (let ch of text.toLowerCase()) {
if (/^\p{L}$/u.test(ch)) {
if (vowels.includes(ch)) {
result.vowels += 1;
} else {
result.consonants += 1;
}
}
}
return result;
}
User registration.
#Create a UserRegistry class. The register(username) method: - returns true if the user was added - false if such a user already exists
let users = [];
class UserRegistry {
// your code here
}
Solution
let users = [];
class UserRegistry {
register(username) {
if (users.includes(username)) {
return false;
}
users.push(username);
return true;
}
}
Number classification.
#Write a function that takes an array of numbers and returns an object: - "positive" - "negative" - "zero"
function numberSummary(nums) {
// your code here
}
Solution
function numberSummary(nums) {
let result = {"positive": 0, "negative": 0, "zero": 0};
for (let n of nums) {
if (n > 0) {
result["positive"] += 1;
} else if (n < 0) {
result["negative"] += 1;
} else {
result["zero"] += 1;
}
}
return result;
}
Shopping cart.
#Create a ShoppingCart class. The add(product, price) method adds a product. The total() method returns the sum of all prices.
class ShoppingCart {
// your code here
}
Solution
class ShoppingCart {
constructor() {
this.items = {};
}
add(product, price) {
this.items[product] = price;
}
total() {
let total = 0;
for (let p of Object.values(this.items)) {
total += p;
}
return total;
}
}
Position of the first occurrence of a character.
#Write a function that takes a string and returns an object where the key is a character, and the value is the position of its first occurrence in the string.
function firstPositions(text) {
// your code here
}
Solution
function firstPositions(text) {
let result = {};
for (let i = 0; i < text.length; i++) {
if (!(text[i] in result)) {
result[text[i]] = i;
}
}
return result;
}
Player score table.
#Create a ScoreTable class. The add(name, ponumbers) method adds points to a player. The top_Player() method returns the name of the player with the highest score.
class ScoreTable {
// your code here
}
Solution
class ScoreTable {
constructor() {
this.scores = {};
}
add(name, points) {
if (name in this.scores) {
this.scores[name] += points;
} else {
this.scores[name] = points;
}
}
topPlayer() {
let names = Object.keys(this.scores);
if (names.length === 0) {
return null;
}
let top = null;
let maxScore = -1;
for (const [name, score] of Object.entries(this.scores)) {
if (score > maxScore) {
maxScore = score;
top = name;
}
}
return top;
}
}
Swapping keys and values.
#Write a function that takes an object and returns a new object where keys and values are swapped. It is guaranteed that the values are unique.
function swapDict(d) {
// your code here
}
Solution
function swapDict(d) {
let result = {};
for (const [k, v] of Object.entries(d)) {
result[v] = k;
}
return result;
}
Text analyzer.
#Create a TextAnalyzer class. The analyze method returns an object: - "chars" — number of characters - "words" — number of words - "lines" — number of lines
class TextAnalyzer {
// your code here
}
Solution
class TextAnalyzer {
constructor(text) {
this.text = text;
}
analyze() {
const chars = this.text.length;
const words = this.text.trim() ? this.text.trim().split(/\s+/).length : 0;
const lines = this.text ? this.text.split("\n").length : 0;
return {
chars,
words,
lines,
};
}
}