JavaScript Sets

Sets in JavaScript are a collection of unique values, where each value can occur only once. Sets are particularly useful for managing collections of items without duplicates.

Concept and Use Cases

Definition: A JavaScript Set is a mutable collection of unique values, where each value can occur only once. Sets are iterable objects and can hold any type of value, whether primitive or object references.

Common Use Cases:

  • Removing duplicates from an array.
  • Checking for the existence of an item in a collection.
  • Performing set operations like union, intersection, and difference.
  • Efficiently managing collections of unique items.

When to Use

  • When you need to store a collection of unique values.
  • When you require efficient lookups for the existence of values.
  • When performing mathematical set operations.

Time and Space Complexity

Time Complexity:

  • Insertion: O(1)
  • Deletion: O(1)
  • Search: O(1)
  • Iteration: O(n)

Space Complexity:

  • O(n), where n is the number of elements in the set.

Set Operations and Methods

Creating Sets

Example:

let emptySet = new Set();
let numberSet = new Set([1, 2, 3, 4, 5]);
let mixedSet = new Set([1, 'two', { three: 3 }, [4, 5]]);

Adding and Removing Elements

Example:

let set = new Set();
set.add(1);
set.add(2);
set.add(2);  // Duplicate, will not be added
console.log(set);  // Output: Set { 1, 2 }

set.delete(1);
console.log(set);  // Output: Set { 2 }

Checking for Existence

Example:

let set = new Set([1, 2, 3]);
console.log(set.has(2));  // Output: true
console.log(set.has(4));  // Output: false

Getting the Size of a Set

Example:

let set = new Set([1, 2, 3]);
console.log(set.size);  // Output: 3

Iterating Over Sets

Example:

let set = new Set([1, 2, 3]);

for (let value of set) {
    console.log(value);
}

set.forEach((value) => {
    console.log(value);
});

Clearing a Set

Example:

let set = new Set([1, 2, 3]);
set.clear();
console.log(set.size);  // Output: 0

Converting Sets to Arrays

Example:

let set = new Set([1, 2, 3]);
let array = Array.from(set);
console.log(array);  // Output: [1, 2, 3]

let spreadArray = [...set];
console.log(spreadArray);  // Output: [1, 2, 3]

Practical Tips and Tricks

  • Removing Duplicates from an Array: Use a set to easily remove duplicates from an array.

    Example:

    let array = [1, 2, 2, 3, 4, 4, 5];
    let uniqueArray = [...new Set(array)];
    console.log(uniqueArray);  // Output: [1, 2, 3, 4, 5]
    
  • Performing Set Operations: Use sets to perform union, intersection, and difference operations.

    Example:

    let setA = new Set([1, 2, 3]);
    let setB = new Set([3, 4, 5]);
    
    // Union
    let union = new Set([...setA, ...setB]);
    console.log(union);  // Output: Set { 1, 2, 3, 4, 5 }
    
    // Intersection
    let intersection = new Set([...setA].filter(x => setB.has(x)));
    console.log(intersection);  // Output: Set { 3 }
    
    // Difference
    let difference = new Set([...setA].filter(x => !setB.has(x)));
    console.log(difference);  // Output: Set { 1, 2 }
    
  • Using Sets for Fast Lookups: Sets provide efficient O(1) lookups for existence checks.

    Example:

    let set = new Set([1, 2, 3, 4, 5]);
    console.log(set.has(3));  // Output: true
    console.log(set.has(6));  // Output: false
    

Common Gotchas

  • Sets Are Iterated in Insertion Order: Sets maintain the order of insertion, which can affect the result of iteration.

    Example:

    let set = new Set([3, 1, 2]);
    console.log([...set]);  // Output: [3, 1, 2]
    
  • NaN and Object References: NaN is considered equal to NaN in sets, and object references are compared by reference, not value.

    Example:

    let set = new Set();
    set.add(NaN);
    set.add(NaN);
    console.log(set);  // Output: Set { NaN }
    
    let obj1 = { a: 1 };
    let obj2 = { a: 1 };
    set.add(obj1);
    set.add(obj2);
    console.log(set);  // Output: Set { NaN, { a: 1 }, { a: 1 } }
    
  • Set Methods Are Case-Sensitive: Be aware that methods like add and has are case-sensitive.

    Example:

    let set = new Set();
    set.add('apple');
    console.log(set.has('Apple'));  // Output: false
    

Advanced Topics

WeakSets

WeakSets are similar to sets but only contain objects and are weakly referenced, meaning they do not prevent garbage collection.

Example:

let weakSet = new WeakSet();
let obj = {};
weakSet.add(obj);
console.log(weakSet.has(obj));  // Output: true

Set Operations Using Utility Functions

Example:

function union(setA, setB) {
    return new Set([...setA, ...setB]);
}

function intersection(setA, setB) {
    return new Set([...setA].filter(x => setB.has(x)));
}

function difference(setA, setB) {
    return new Set([...setA].filter(x => !setB.has(x)));
}

let setA = new Set([1, 2, 3]);
let setB = new Set([3, 4, 5]);

console.log(union(setA, setB));  // Output: Set { 1, 2, 3, 4, 5 }
console.log(intersection(setA, setB));  // Output: Set { 3 }
console.log(difference(setA, setB));  // Output: Set { 1, 2 }

Set Algorithms

Below are some common set algorithms you should be familiar with:

Finding Unique Elements in an Array

Finding unique elements in an array involves removing duplicate values.

Example:

let array = [1, 2, 2, 3, 4, 4, 5];
let uniqueSet = new Set(array);
let uniqueArray = [...uniqueSet];
console.log(uniqueArray);  // Output: [1, 2, 3, 4, 5]

Counting Unique Elements

Counting unique elements determines the number of distinct values in an array.

Example:

function countUniqueElements(arr) {
    return new Set(arr).size;
}

let array = [1, 2, 2, 3, 4, 4, 5];
console.log(countUniqueElements(array));  // Output: 5

Finding Intersection of Multiple Sets

Finding the intersection of multiple sets identifies elements common to all sets.

Example:

function intersectionOfSets(...sets) {
    return sets.reduce((acc, set) => new Set([...acc].filter(x => set.has(x))));
}

let setA = new Set([1, 2, 3]);
let setB = new Set([2, 3, 4]);
let setC = new Set([3, 4, 5]);

console.log(intersectionOfSets(setA, setB, setC));  // Output: Set { 3 }

Interview Tips and Tricks

  • Understand Set Operations: Be comfortable with performing union, intersection, and difference operations using sets.

  • Practice Common Set Use Cases: Familiarize yourself with removing duplicates, checking for unique elements, and performing efficient lookups.

  • Consider Edge Cases: Handle scenarios with empty sets, sets with a single element, and sets with complex object references.

Common Mistakes

  • Forgetting About Reference Equality: Objects are compared by reference, not value. Be cautious when adding objects to a set.

  • Ignoring Set Order: Sets maintain the insertion order, which may affect the outcome of iterations and operations.

  • Misusing WeakSet: WeakSets can only contain objects and do not have methods like forEach or size.

By mastering JavaScript sets and understanding their intricacies, you will be well-equipped to handle a variety of interview questions and real-world problems involving collections of unique values. Regular practice and a solid grasp of advanced topics will deepen your understanding and improve your problem-solving skills.

Practice Problems

Given two arrays, find the elements that are common to both arrays and return them in a single array.

Loading...

Unique Email AddressesDifficulty: Easy

The goal is to write an algorithm that filters out duplicate and malformed email addresses from a list, returning the unique ones in the correct format.

Loading...

Valid SudokuDifficulty: Medium

Determine whether a given Sudoku puzzle is valid, following the standard rules where each row, column, and 3x3 sub-grid must contain the numbers 1-9 without repetition.

Loading...

Let's continue exploring the next page. Take your time, and proceed when you're ready.

Lesson completed?

Found a bug, typo, or have feedback?

Let me know