JavaScript · Syntax · Beginner

Set, objects, error handling

15 tasks

JavaScript practice with Sets, objects, and error handling: unique values, common symbols, try/catch, safe data handling, word grouping, and string parsing.

Sets — uniqueness and set operations

#
A Set is a collection of unique values. Adding the same value twice has no effect — duplicates are silently ignored. ```javascript const numbers = [1, 2, 2, 3, 3, 3]; const unique = new Set(numbers); console.log([...unique]); // [1, 2, 3] ``` new Set(array) creates a set from an array. The spread operator ... converts it back to an array. Checking membership with has() is much faster than checking an array with includes(), especially for large collections: ```javascript const allowed = new Set(["admin", "editor", "viewer"]); if (allowed.has(userRole)) { // grant access } ``` Set operations — JavaScript has no built-in & and | operators for sets, but you can compose them from filter and spread: ```javascript const a = new Set([1, 2, 3, 4]); const b = new Set([3, 4, 5, 6]); // Intersection — elements in both const intersection = new Set([...a].filter(x => b.has(x))); // Union — elements in either const union = new Set([...a, ...b]); // Difference — in a but not in b const difference = new Set([...a].filter(x => !b.has(x))); ``` Finding common characters between two strings: ```javascript function commonChars(s1, s2) { const set1 = new Set(s1); const set2 = new Set(s2); return [...set1].filter(c => set2.has(c)); } ``` new Set(string) iterates the string and stores each unique character. The filter then keeps only those that appear in the second set. When to use a Set instead of an array: when you need uniqueness, fast membership testing, or set operations. When order matters or you need duplicates, stick with an array.

Object patterns — grouping and filtering

#
Plain objects {} are JavaScript's dictionary. In these exercises functions receive and return objects, so the core operations are iteration and transformation. Grouping items by a property — build an object where the key is the group and the value is an array: ```javascript function firstLetterStats(words) { const result = {}; for (const word of words) { const letter = word[0]; if (!(letter in result)) { result[letter] = []; } result[letter].push(word); } return result; } ``` Filtering an object — build a new object with only entries that pass a condition. Object.entries() gives you [key, value] pairs: ```javascript function adultsOnly(data) { const result = {}; for (const [name, age] of Object.entries(data)) { if (age > 18) { result[name] = age; } } return result; } ``` Swapping keys and values — works only when values are unique: ```javascript function swapDict(obj) { const result = {}; for (const [k, v] of Object.entries(obj)) { result[v] = k; } return result; } ``` Removing null/undefined values: ```javascript function removeNulls(obj) { const result = {}; for (const [k, v] of Object.entries(obj)) { if (v !== null && v !== undefined) { result[k] = v; } } return result; } ``` Use strict equality !== null rather than loose != null here — even though != null also catches undefined, it is less explicit about your intent.

Handling errors with try/catch

#
Exceptions in JavaScript signal that something went wrong at runtime. parseInt("hello") does not throw — it returns NaN — but many other operations do throw: accessing a property on null or undefined raises a TypeError, JSON.parse on invalid input throws a SyntaxError. try/catch lets you react to an exception instead of crashing: ```javascript function safeSum(text) { let total = 0; for (const part of text.split(" ")) { try { const n = Number(part); if (isNaN(n)) throw new Error("not a number"); total += n; } catch (e) { // skip parts that are not valid numbers } } return total; } ``` The try block contains the code that might fail. If an exception is thrown, execution jumps to the catch block. The error object e is available inside catch — you can inspect e.message for details. A common pattern: try to parse input, fall back to a default if parsing fails: ```javascript try { const data = JSON.parse(rawInput); process(data); } catch (e) { console.log("Invalid JSON, using defaults"); process({}); } ``` You can also use a finally block for cleanup that should always run, even if an exception was thrown: ```javascript try { riskyOperation(); } catch (e) { console.log("Error:", e.message); } finally { cleanup(); // always runs } ``` Use try/catch for genuinely exceptional situations — invalid user input, network failures, JSON parsing. Do not use it as a substitute for checking conditions you can check directly (like array.length > 0 before accessing array[0]).
01

Unique positive values.

#

Write a function that takes an array of numbers and returns a Set of unique positive values.

function uniquePositive(nums) {
    // your code here
}
Solution
function uniquePositive(nums) {
    let result = new Set([]);
    for (let n of nums) {
        if (n > 0) {
            result.add(n);
        }
    }
    return result;
}

// or like this: check positivity before adding to the Set
let numbers = [1, -2, 3, 1, 0, 3, 5];
let result = new Set();

for (let n of numbers) {
    if (n > 0) {
        result.add(n);
    }
}

console.log(result);
02

Common characters of two strings.

#

Write a function that takes two strings and returns a Set of common characters.

function commonChars(a, b) {
    // your code here
}
Solution
function commonChars(a, b) {
    return new Set([...a].filter(char => new Set(b).has(char)));
}
03

Average price of products.

#

Write a function that takes an object with product prices and returns the average price. If the object is empty — return 0.

function averagePrice(prices) {
    // your code here
}
Solution
function averagePrice(prices) {
    const values = Object.values(prices);
    if (values.length === 0) {
        return 0;
    }

    let total = 0;
    for (let price of values) {
        total += price;
    }

    return total / values.length;
}
04

Sum of numbers from a string.

#

Write a function that takes a string with numbers separated by spaces and returns the sum of these numbers. If a value is not a number — skip it.

function safeSum(text) {
    // your code here
}
Solution
function safeSum(text) {
    let total = 0;

    for (let part of text.trim().split(/\s+/)) {
        const value = Number(part);
        if (!Number.isNaN(value)) {
            total += value;
        }
    }

    return total;
}
05

Grouping by the first letter.

#

Write a function that takes an array of words and returns an object where: - the key is the first letter of the word - the value is the number of words starting with that letter

function firstLetterStats(words) {
    // your code here
}
Solution
function firstLetterStats(words) {
    let result = {};

    for (let w of words) {
        if (!w) {
            continue;
        }

        let key = w[0];

        if (key in result) {
            result[key] += 1;
        } else {
            result[key] = 1;
        }
    }

    return result;
}
06

Intersection and difference of Set.

#

Write a function that takes two Set objects and returns: - their intersection - their difference (first minus second)

function setOperations(a, b) {
    // your code here
}
Solution
function setOperations(a, b) {
    return {
        intersection: new Set(
            [...a].filter(value => b.has(value))
        ),

        difference: new Set(
            [...a].filter(value => !b.has(value))
        ),
    };
}
07

Filter older than 18.

#

Write a function that takes an object {name: age} and returns an object only with those who are older than 18.

function adultsOnly(data) {
    // your code here
}
Solution
function adultsOnly(data) {
    let result = {};
    for (const [name, age] of Object.entries(data)) {
        if (age > 18) {
            result[name] = age;
        }
    }
    return result;
}
08

Set of value types.

#

Write a function that takes an array of values and returns a Set of their types.

function valueTypes(values) {
    // your code here
}
Solution
function valueTypes(values) {
    let result = new Set();
    for (let v of values) {
        result.add(typeof v);
    }
    return result;
}
09

Best student by score.

#

Write a function that takes an object with students' scores and returns the name of the student with the highest score. If the object is empty — return null.

function bestStudent(scores) {
    // your code here
}
Solution
function bestStudent(scores) {
    if (Object.keys(scores).length === 0) {
        return null;
    }

    let best = null;
    let maxScore = -1;

    for (const [name, score] of Object.entries(scores)) {
        if (score > maxScore) {
            maxScore = score;
            best = name;
        }
    }

    return best;
}
10

Word counting.

#

Write a function that takes a string and returns an object with the count of each word.

function wordFrequency(text) {
    // your code here
}
Solution
function wordFrequency(text) {
    const result = {};

    for (let word of text.trim().split(/\s+/)) {
        if (!word) continue;
        word = word.toLowerCase();
        if (word in result) {
            result[word] += 1;
        } else {
            result[word] = 1;
        }
    }

    return result;
}
11

Even and odd in an object.

#

Write a function that takes an array of numbers and returns an object: - "even" — count of even numbers - "odd" — count of odd numbers

function evenOddStats(nums) {
    // your code here
}
Solution
function evenOddStats(nums) {
    let result = {"even": 0, "odd": 0};
    for (let n of nums) {
        if (n % 2 === 0) {
            result["even"] += 1;
        } else {
            result["odd"] += 1;
        }
    }
    return result;
}
12

Removing null values.

#

Write a function that takes an object and returns a new object without pairs where the value is null.

function removeNulls(d) {
    // your code here
}
Solution
function removeNulls(d) {
    let result = {};
    for (const [k, v] of Object.entries(d)) {
        if (v !== null) {
            result[k] = v;
        }
    }
    return result;
}

// or like this: create a new object without changing the original one
let data = {a: 1, b: null, c: 3};
let result = {};

for (let key in data) {
    if (data[key] !== null) {
        result[key] = data[key];
    }
}

console.log(result);
13

Unique words from strings.

#

Write a function that takes an array of strings and returns a Set of all unique words.

function uniqueWords(lines) {
    // your code here
}
Solution
function uniqueWords(lines) {
    const result = new Set();

    for (let line of lines) {
        for (let word of line.trim().split(/\s+/)) {
            if (word) {
                result.add(word.toLowerCase());
            }
        }
    }

    return result;
}
14

Digits, letters, and other symbols.

#

Write a function that takes a string and returns an object: - "digits" — count of digits - "letters" — count of letters - "others" — count of all other symbols

function charStats(text) {
    // your code here
}
Solution
function charStats(text) {
    let result = {"digits": 0, "letters": 0, "others": 0};
    for (let ch of text) {
        if (/^\d$/.test(ch)) {
            result["digits"] += 1;
        } else if (/^\p{L}$/u.test(ch)) {
            result["letters"] += 1;
        } else {
            result["others"] += 1;
        }
    }
    return result;
}
15

Set of words by length.

#

Write a function that takes an array of words and returns an object where: - the key is the word length - the value is a Set of words of that length

function groupByLength(words) {
    // your code here
}
Solution
function groupByLength(words) {
    let result = {};

    for (let w of words) {
        let l = w.length;

        if (!(l in result)) {
            result[l] = new Set();
        }

        result[l].add(w);
    }

    return result;
}