javascript
exercises
exercises.js⚡javascript
/**
* =====================================================
* 4.5 FOR...OF AND FOR...IN LOOPS - EXERCISES
* =====================================================
* Practice specialized iteration
*/
/**
* Exercise 1: Sum Array
*
* Calculate the sum of all numbers in an array using for...of.
*/
function sumArray(numbers) {
// TODO: Use for...of to sum all numbers
}
// Test cases:
console.log('Exercise 1:');
console.log(sumArray([1, 2, 3, 4, 5])); // 15
console.log(sumArray([10, 20, 30])); // 60
console.log(sumArray([])); // 0
/**
* Exercise 2: Find Maximum
*
* Find the maximum value in an array using for...of.
*/
function findMax(numbers) {
// TODO: Use for...of to find the maximum
}
// Test cases:
console.log('\nExercise 2:');
console.log(findMax([3, 7, 2, 9, 5])); // 9
console.log(findMax([-5, -2, -8])); // -2
console.log(findMax([42])); // 42
/**
* Exercise 3: Count Characters
*
* Count occurrences of each character in a string using for...of.
* Return an object with character counts.
*/
function countCharacters(str) {
// TODO: Use for...of to count each character
}
// Test cases:
console.log('\nExercise 3:');
console.log(countCharacters('hello'));
// { h: 1, e: 1, l: 2, o: 1 }
console.log(countCharacters('aabbcc'));
// { a: 2, b: 2, c: 2 }
/**
* Exercise 4: Get Object Keys
*
* Return an array of all own property keys using for...in.
* Don't include inherited properties.
*/
function getOwnKeys(obj) {
// TODO: Use for...in with hasOwnProperty
}
// Test cases:
console.log('\nExercise 4:');
const parent = { inherited: true };
const child = Object.create(parent);
child.own1 = 'a';
child.own2 = 'b';
console.log(getOwnKeys(child)); // ["own1", "own2"]
console.log(getOwnKeys({ x: 1, y: 2, z: 3 })); // ["x", "y", "z"]
/**
* Exercise 5: Object Values Sum
*
* Sum all numeric values in an object.
*/
function sumObjectValues(obj) {
// TODO: Use for...in or Object methods
}
// Test cases:
console.log('\nExercise 5:');
console.log(sumObjectValues({ a: 10, b: 20, c: 30 })); // 60
console.log(sumObjectValues({ x: 5, y: 'text', z: 15 })); // 20 (skip non-numbers)
/**
* Exercise 6: First Duplicate
*
* Find the first duplicate element in an array using for...of.
* Return undefined if no duplicates.
*/
function firstDuplicate(arr) {
// TODO: Use for...of with a Set to track seen values
}
// Test cases:
console.log('\nExercise 6:');
console.log(firstDuplicate([1, 2, 3, 2, 4])); // 2
console.log(firstDuplicate([1, 2, 3, 4])); // undefined
console.log(firstDuplicate(['a', 'b', 'a'])); // "a"
/**
* Exercise 7: Map from Entries
*
* Create a Map from an array of key-value pairs using for...of.
*/
function createMap(entries) {
// TODO: Build a Map from entries array
}
// Test cases:
console.log('\nExercise 7:');
const map1 = createMap([
['a', 1],
['b', 2],
['c', 3],
]);
console.log(map1.get('b')); // 2
console.log(map1.size); // 3
/**
* Exercise 8: Filter Object
*
* Create a new object with only properties that pass the predicate.
*/
function filterObject(obj, predicate) {
// TODO: Filter object properties using for...in
// predicate(value, key) returns true to include
}
// Test cases:
console.log('\nExercise 8:');
const nums = { a: 1, b: 2, c: 3, d: 4 };
console.log(filterObject(nums, (v) => v > 2)); // { c: 3, d: 4 }
console.log(filterObject(nums, (v, k) => k !== 'b')); // { a: 1, c: 3, d: 4 }
/**
* Exercise 9: Flatten Array
*
* Flatten a 2D array into a 1D array using for...of.
*/
function flatten(arr2d) {
// TODO: Flatten using nested for...of
}
// Test cases:
console.log('\nExercise 9:');
console.log(
flatten([
[1, 2],
[3, 4],
[5, 6],
])
); // [1, 2, 3, 4, 5, 6]
console.log(flatten([['a'], ['b', 'c'], ['d']])); // ["a", "b", "c", "d"]
/**
* Exercise 10: Merge Objects
*
* Merge multiple objects into one. Later objects override earlier ones.
*/
function mergeObjects(...objects) {
// TODO: Merge all objects using for...of and for...in
}
// Test cases:
console.log('\nExercise 10:');
console.log(mergeObjects({ a: 1 }, { b: 2 }, { c: 3 }));
// { a: 1, b: 2, c: 3 }
console.log(mergeObjects({ a: 1, b: 2 }, { b: 3, c: 4 }));
// { a: 1, b: 3, c: 4 }
// =====================================================
// BONUS CHALLENGES
// =====================================================
/**
* Bonus 1: Group By Property
*
* Group an array of objects by a specified property.
*/
function groupBy(arr, property) {
// TODO: Group objects by the given property
}
console.log('\nBonus 1:');
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
];
console.log(groupBy(people, 'age'));
// { 25: [{name: "Alice"...}, {name: "Charlie"...}], 30: [{name: "Bob"...}] }
/**
* Bonus 2: Deep Flatten
*
* Flatten an arbitrarily nested array.
*/
function deepFlatten(arr) {
// TODO: Recursively flatten
}
console.log('\nBonus 2:');
console.log(deepFlatten([1, [2, [3, [4]], 5]])); // [1, 2, 3, 4, 5]
/**
* Bonus 3: Object Difference
*
* Find properties that exist in obj1 but not in obj2,
* or have different values.
*/
function objectDiff(obj1, obj2) {
// TODO: Find differences
}
console.log('\nBonus 3:');
console.log(objectDiff({ a: 1, b: 2, c: 3 }, { a: 1, c: 4 }));
// { b: 2, c: 3 } (b is missing in obj2, c has different value)
// =====================================================
// SOLUTIONS (Uncomment to check your answers)
// =====================================================
/*
// Exercise 1 Solution:
function sumArray(numbers) {
let sum = 0;
for (const num of numbers) {
sum += num;
}
return sum;
}
// Exercise 2 Solution:
function findMax(numbers) {
if (numbers.length === 0) return undefined;
let max = numbers[0];
for (const num of numbers) {
if (num > max) max = num;
}
return max;
}
// Exercise 3 Solution:
function countCharacters(str) {
const counts = {};
for (const char of str) {
counts[char] = (counts[char] || 0) + 1;
}
return counts;
}
// Exercise 4 Solution:
function getOwnKeys(obj) {
const keys = [];
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
keys.push(key);
}
}
return keys;
}
// Exercise 5 Solution:
function sumObjectValues(obj) {
let sum = 0;
for (const key in obj) {
if (typeof obj[key] === "number") {
sum += obj[key];
}
}
return sum;
}
// Exercise 6 Solution:
function firstDuplicate(arr) {
const seen = new Set();
for (const item of arr) {
if (seen.has(item)) {
return item;
}
seen.add(item);
}
return undefined;
}
// Exercise 7 Solution:
function createMap(entries) {
const map = new Map();
for (const [key, value] of entries) {
map.set(key, value);
}
return map;
}
// Exercise 8 Solution:
function filterObject(obj, predicate) {
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
if (predicate(obj[key], key)) {
result[key] = obj[key];
}
}
}
return result;
}
// Exercise 9 Solution:
function flatten(arr2d) {
const result = [];
for (const row of arr2d) {
for (const item of row) {
result.push(item);
}
}
return result;
}
// Exercise 10 Solution:
function mergeObjects(...objects) {
const result = {};
for (const obj of objects) {
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = obj[key];
}
}
}
return result;
}
// Bonus 1 Solution:
function groupBy(arr, property) {
const groups = {};
for (const item of arr) {
const key = item[property];
if (!groups[key]) {
groups[key] = [];
}
groups[key].push(item);
}
return groups;
}
// Bonus 2 Solution:
function deepFlatten(arr) {
const result = [];
for (const item of arr) {
if (Array.isArray(item)) {
for (const nested of deepFlatten(item)) {
result.push(nested);
}
} else {
result.push(item);
}
}
return result;
}
// Bonus 3 Solution:
function objectDiff(obj1, obj2) {
const diff = {};
for (const key in obj1) {
if (!(key in obj2) || obj1[key] !== obj2[key]) {
diff[key] = obj1[key];
}
}
return diff;
}
*/