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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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.
#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,
};
}
}