javascript
exercises
exercises.js⚡javascript
/**
* 6.3 Maps and Sets - Exercises
* Practice with ES6 Collection Data Structures
*/
// ============================================
// EXERCISE 1: Basic Map Operations
// ============================================
/**
* Create a Map to store student grades
* - Add 5 students with their grades
* - Calculate the average grade
* - Find the student with highest grade
* - Return an object with: average, highest: {name, grade}
*/
function studentGrades() {
// Your code here
}
// console.log(studentGrades());
// Expected: { average: XX, highest: { name: 'StudentName', grade: XX } }
// ============================================
// EXERCISE 2: Object to Map Conversion
// ============================================
/**
* Convert a nested object to a Map where:
* - Keys are dot-notation paths
* - Values are the leaf values
*
* Example: { a: { b: 1, c: 2 } } => Map { 'a.b' => 1, 'a.c' => 2 }
*/
function flattenToMap(obj, prefix = '') {
// Your code here
}
// const nested = { user: { name: 'Alice', address: { city: 'NYC', zip: '10001' } } };
// console.log([...flattenToMap(nested)]);
// Expected: [['user.name', 'Alice'], ['user.address.city', 'NYC'], ['user.address.zip', '10001']]
// ============================================
// EXERCISE 3: Remove Duplicates Preserving Order
// ============================================
/**
* Remove duplicate objects from array based on a key
* Preserve the first occurrence
*/
function removeDuplicatesByKey(arr, key) {
// Your code here
}
// const users = [
// { id: 1, name: 'Alice' },
// { id: 2, name: 'Bob' },
// { id: 1, name: 'Alice Updated' },
// { id: 3, name: 'Charlie' }
// ];
// console.log(removeDuplicatesByKey(users, 'id'));
// Expected: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]
// ============================================
// EXERCISE 4: Set Operations Class
// ============================================
/**
* Create a SuperSet class that extends Set with:
* - union(otherSet): returns new SuperSet with all elements
* - intersection(otherSet): returns new SuperSet with common elements
* - difference(otherSet): returns new SuperSet with elements not in otherSet
* - isSubsetOf(otherSet): returns boolean
* - isSupersetOf(otherSet): returns boolean
*/
class SuperSet extends Set {
// Your code here
}
// const a = new SuperSet([1, 2, 3, 4]);
// const b = new SuperSet([3, 4, 5, 6]);
// console.log([...a.union(b)]); // [1, 2, 3, 4, 5, 6]
// console.log([...a.intersection(b)]); // [3, 4]
// console.log([...a.difference(b)]); // [1, 2]
// ============================================
// EXERCISE 5: LRU Cache with Map
// ============================================
/**
* Implement an LRU (Least Recently Used) Cache using Map
* - constructor(capacity): max items to store
* - get(key): return value or -1, marks as recently used
* - put(key, value): add/update value, evict LRU if at capacity
*
* Hint: Map maintains insertion order, use delete+set to move to end
*/
class LRUCache {
// Your code here
}
// const cache = new LRUCache(3);
// cache.put('a', 1);
// cache.put('b', 2);
// cache.put('c', 3);
// console.log(cache.get('a')); // 1 (moves 'a' to recently used)
// cache.put('d', 4); // Evicts 'b' (least recently used)
// console.log(cache.get('b')); // -1 (was evicted)
// ============================================
// EXERCISE 6: Word Frequency Counter
// ============================================
/**
* Count word frequency in a text, returning a Map
* - Ignore case
* - Ignore punctuation
* - Return sorted by frequency (descending)
*/
function wordFrequency(text) {
// Your code here
}
// const text = "The quick brown fox jumps over the lazy dog. The dog was not amused.";
// console.log([...wordFrequency(text)]);
// Expected: [['the', 3], ['dog', 2], ...]
// ============================================
// EXERCISE 7: Two Sum with Map
// ============================================
/**
* Given an array of numbers and a target sum,
* return indices of two numbers that add up to target
* Use Map for O(n) solution
*/
function twoSum(nums, target) {
// Your code here
}
// console.log(twoSum([2, 7, 11, 15], 9)); // [0, 1]
// console.log(twoSum([3, 2, 4], 6)); // [1, 2]
// ============================================
// EXERCISE 8: Group Anagrams with Map
// ============================================
/**
* Group words that are anagrams of each other
* Return a Map where key is sorted letters, value is array of words
*/
function groupAnagrams(words) {
// Your code here
}
// console.log(groupAnagrams(['eat', 'tea', 'tan', 'ate', 'nat', 'bat']));
// Expected Map: { 'aet' => ['eat', 'tea', 'ate'], 'ant' => ['tan', 'nat'], 'abt' => ['bat'] }
// ============================================
// EXERCISE 9: WeakMap for Private Properties
// ============================================
/**
* Create a Password class that stores passwords securely using WeakMap
* - setPassword(password): hash and store password
* - checkPassword(password): verify password
* - changePassword(oldPass, newPass): change if old is correct
*
* Simple hash: password.split('').reduce((a, c) => a + c.charCodeAt(0), 0)
*/
const _passwords = new WeakMap();
class Password {
// Your code here
}
// const pwd = new Password();
// pwd.setPassword('secret123');
// console.log(pwd.checkPassword('secret123')); // true
// console.log(pwd.checkPassword('wrong')); // false
// console.log(pwd.password); // undefined
// ============================================
// EXERCISE 10: Find First Unique Character
// ============================================
/**
* Find the first non-repeating character in a string
* Return its index, or -1 if none exists
* Use Map to count occurrences
*/
function firstUniqChar(s) {
// Your code here
}
// console.log(firstUniqChar('leetcode')); // 0 ('l')
// console.log(firstUniqChar('loveleetcode')); // 2 ('v')
// console.log(firstUniqChar('aabb')); // -1
// ============================================
// EXERCISE 11: Intersection of Multiple Arrays
// ============================================
/**
* Find elements that appear in ALL arrays
* Use Set operations
*/
function intersectionAll(...arrays) {
// Your code here
}
// console.log(intersectionAll([1, 2, 3], [2, 3, 4], [3, 4, 5])); // [3]
// console.log(intersectionAll([1, 2], [2, 3], [2, 4])); // [2]
// ============================================
// EXERCISE 12: Event Emitter with Map
// ============================================
/**
* Create an EventEmitter class using Map:
* - on(event, callback): register listener
* - off(event, callback): remove listener
* - emit(event, ...args): call all listeners with args
* - once(event, callback): listener that fires only once
*/
class EventEmitter {
// Your code here
}
// const emitter = new EventEmitter();
// const handler = (data) => console.log('Received:', data);
// emitter.on('message', handler);
// emitter.emit('message', 'Hello!'); // Logs: Received: Hello!
// emitter.off('message', handler);
// emitter.emit('message', 'Hello again!'); // Nothing
// ============================================
// BONUS: Implement a Trie with Map
// ============================================
/**
* Implement a Trie (prefix tree) using Maps
* - insert(word): add a word
* - search(word): check if word exists
* - startsWith(prefix): check if any word starts with prefix
* - getWordsWithPrefix(prefix): return all words with prefix
*/
class Trie {
// Your code here
}
// const trie = new Trie();
// trie.insert('apple');
// trie.insert('app');
// trie.insert('application');
// console.log(trie.search('app')); // true
// console.log(trie.search('ap')); // false
// console.log(trie.startsWith('app')); // true
// console.log(trie.getWordsWithPrefix('app')); // ['app', 'apple', 'application']
// ============================================
// SOLUTIONS (uncomment to check)
// ============================================
/*
// Solution 1
function studentGrades() {
const grades = new Map([
['Alice', 95],
['Bob', 87],
['Charlie', 92],
['Diana', 78],
['Eve', 88]
]);
let sum = 0;
let highest = { name: '', grade: -Infinity };
for (const [name, grade] of grades) {
sum += grade;
if (grade > highest.grade) {
highest = { name, grade };
}
}
return {
average: sum / grades.size,
highest
};
}
// Solution 5
class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return -1;
const value = this.cache.get(key);
// Move to end (most recently used)
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
put(key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
} else if (this.cache.size >= this.capacity) {
// Delete first (least recently used)
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, value);
}
}
// Solution 7
function twoSum(nums, target) {
const seen = new Map();
for (let i = 0; i < nums.length; i++) {
const complement = target - nums[i];
if (seen.has(complement)) {
return [seen.get(complement), i];
}
seen.set(nums[i], i);
}
return [];
}
*/