JavaScript Set: In-Depth Guide & Array vs Set Comparison

This document provides an extensive explanation of JavaScript's Set object. It covers all details from basic usage to advanced techniques, complete with examples and use cases. An additional section at the end compares Arrays and Sets.

Overview of JavaScript Set

A Set is a built-in object (introduced in ES6) for storing unique values of any type – whether primitives or object references. Sets have a number of distinctive properties including uniqueness of elements, maintained insertion order, dynamic size, and iterable capability.

Creating a Set

You create a Set using the Set constructor. Passing an iterable (like an array) will automatically remove duplicates.


// Creating an empty Set
const mySet = new Set();

// Creating a Set from an array (duplicates removed)
const numberSet = new Set([1, 2, 2, 3, 4, 4, 5]);
console.log(numberSet); // Output: Set { 1, 2, 3, 4, 5 }
      

Set Methods and Properties

1. add(value)

Adds a new element to the Set. If the element exists, the Set remains unchanged.


const fruits = new Set();
fruits.add("apple");
fruits.add("banana");
fruits.add("apple"); // Duplicate, not added
console.log(fruits); // Set { 'apple', 'banana' }
      

2. delete(value)

Removes the specified element from the Set. Returns true if successful, false otherwise.


const numbers = new Set([1, 2, 3]);
console.log(numbers.delete(2)); // true
console.log(numbers);           // Set { 1, 3 }
      

3. has(value)

Returns true if the Set contains the value, otherwise false.


const colors = new Set(["red", "green", "blue"]);
console.log(colors.has("green")); // true
console.log(colors.has("yellow")); // false
      

4. clear()

Removes all elements from the Set.


const items = new Set([1, 2, 3, 4]);
items.clear();
console.log(items); // Set {}
      

5. size (Property)

Returns the number of unique elements in the Set.


const letters = new Set(["a", "b", "c"]);
console.log(letters.size); // 3
      

6. Iteration Methods

Since Sets are iterable, you can loop through them with several techniques:

a. forEach(callback)


const animals = new Set(["cat", "dog", "rabbit"]);
animals.forEach((value, valueAgain, set) => {
  console.log(value);
});
      

b. Iterator methods: values(), keys(), entries()

values() returns an iterator over the Set's values. In a Set, keys() is identical to values(). entries() returns an iterator of [value, value] pairs.


const setExample = new Set(["x", "y", "z"]);

// Using for...of with values():
for (const value of setExample.values()) {
  console.log(value); // x, y, z
}

// Using entries():
for (const [key, value] of setExample.entries()) {
  console.log(key, value); // x x, y y, z z
}
      

Use Cases for Sets

  1. Removing duplicates:
    
    const numbers = [1, 2, 2, 3, 4, 4, 5];
    const uniqueNumbers = [...new Set(numbers)];
    console.log(uniqueNumbers); // [1, 2, 3, 4, 5]
              
  2. Membership testing:
    
    const items = new Set(["apple", "banana", "orange"]);
    if (items.has("banana")) {
      console.log("Banana exists!");
    }
              
  3. Caching/Tracking unique items:

    Use a Set to cache results or track identifiers ensuring no duplicates.

  4. Mathematical set operations:

    You can implement union, intersection, and difference using Sets:

    
    // Union: elements in either set
    function union(setA, setB) {
      return new Set([...setA, ...setB]);
    }
    
    // Intersection: elements in both sets
    function intersection(setA, setB) {
      return new Set([...setA].filter(x => setB.has(x)));
    }
    
    // Difference: elements in setA not in setB
    function difference(setA, setB) {
      return new Set([...setA].filter(x => !setB.has(x)));
    }
              

Advanced Details and Considerations

Memory and Performance

Memory Efficiency: Each value is stored only once which is helpful when working with large data sets.
Performance: Most Set operations such as add and has have an average time complexity of O(1).

Equality Checking

Sets use the Same-value-zero equality (similar to ===) for determining uniqueness. Note that:


const set = new Set();
set.add(NaN);
set.add(NaN);
console.log(set.size); // 1
      

Converting Between Data Structures

You can easily convert a Set to an array and vice versa:


// Set to Array:
const setValues = new Set([1, 2, 3]);
const arr1 = [...setValues];
const arr2 = Array.from(setValues);

// Array to Set (removes duplicates):
const arr = [1, 1, 2, 3, 3];
const uniqueSet = new Set(arr);
      

Iteration Techniques

Standard ways to iterate over a Set:


// for...of loop:
for (const value of uniqueSet) {
  console.log(value);
}

// Using forEach:
uniqueSet.forEach(value => console.log(value));
      

WeakSet vs. Set

While Set can store any type of value, WeakSet only stores objects and holds weak references. This means that objects in a WeakSet can be garbage-collected if there are no other references.

Array vs Set

Both Arrays and Sets are used to store collections of data. However, there are key differences between them:

Feature Array Set
Duplicates Allowed (can have duplicate elements) Not Allowed (each value must be unique)
Order Maintains order of insertion; supports random access by index Maintains insertion order for iteration, but no index-based access
Iteration Can be iterated with loops, forEach, map, etc. Iterable using for...of, forEach, values(), etc.
Performance Searching for an element (using indexOf, includes) is O(n) Checking for existence of an element (using has()) is generally O(1)
Use Cases Ordered collections, lists where order and duplicates matter Collections where uniqueness is essential, fast membership testing, and deduplication

In summary, use an Array when you need to store elements in a specific order with possible duplicates. Choose a Set when you need to maintain a unique collection of items with efficient membership testing.

Summary

JavaScript Sets are a powerful tool for managing unique collections. They are simple to use, offer a clean API for common set operations, and help with tasks like deduplication and membership testing. Knowing when to use an Array or a Set will help you write more efficient and cleaner code.