Set
1. Definition
A Set is a constructor used to generate a Set data structure, which can accept an array (or any other iterable data structure) as an argument for initialization. It allows storing values of any type, whether primitive or object references.
2. Features
- Unique Values: A Set automatically removes duplicates and will not contain duplicate values. (The following rules apply for identity checks)
- +0 and -0 are considered identical when checking for uniqueness, so they do not repeat.
- undefined and undefined are identical, so they do not repeat.
- NaN and NaN are not strictly identical, but in a Set, NaN is considered equal to NaN, so only one NaN can exist.
- Any Data Type: Sets can store both primitive types (like strings and numbers) and reference types (like objects and functions).
- Ordered: The values in a Set are ordered based on the insertion sequence.
- Suitable for Set Operations: Sets efficiently support operations like intersections, unions, and differences.
3. Properties and Methods
Properties/Methods | Description |
new Set() | Creates an empty Set instance |
add(value) | Adds a value, returning the Set itself (supports chaining) |
delete(value) | Deletes a value; returns true if successful, false otherwise |
has(value) | Checks if a specific value exists in the Set |
clear() | Clears all members; no return value |
keys() | Returns an iterator with all the values (same as .values()) |
values() | Returns an iterator with all the values |
entries() | Returns an iterator of [value, value] pairs |
forEach(callback) | Iterates over each value and executes the callback function |
Example Code
const set = new Set(); // Adding values set.add(1); set.add(5); set.add(1); // Duplicate values are ignored set.add('hello'); // Checking if values exist console.log(set.has(5)); // Output: true console.log(set.has(10)); // Output: false // Getting the Set size console.log(set.size); // Output: 3 // Iterating over Set set.forEach(value => { console.log(value); }); // Output: // 1 // 5 // hello // Deleting a value set.delete(5); console.log(set.size); // Output: 2 // Clearing the Set set.clear(); console.log(set.size); // Output: 0
Advantages (Compared to Arrays)
Every item in a Set must be unique.
- Checking for elements
- Deleting elements: Elements can be removed directly using their value.
- Storing NaN: NaN cannot be found using indexOf() or includes() in arrays, but Set can store this value.
- Removing duplicates
- The time complexity for Set operations is O(1), while for arrays, it is O(n).
Applications
Array.from
This method can convert a Set to an array.
- Array Deduplication
Set is a natural tool for removing duplicates, and it is more concise and efficient than traditional filter or indexOf operations.
const arr = [1, 2, 3, 3, 4, 4, 5]; const uniqueArr = [...new Set(arr)]; console.log(uniqueArr); // [1, 2, 3, 4, 5]
- Checking if a value exists in a Set
Set‘s performance is better than arrays’ includes method, especially for large datasets.
const visitedPages = new Set(); function visitPage(page) { if (visitedPages.has(page)) { console.log(`${page} already visited.`); } else { visitedPages.add(page); console.log(`${page} is visited for the first time.`); } } // 示例 visitPage('home'); // 输出: home is visited for the first time. visitPage('home'); // 输出: home already visited.
- Implementing Union, Intersection, and Difference, such as for permission management or tag filtering.
const setA = new Set([1, 2, 3]); const setB = new Set([2, 3, 4]); // 并集 const union = new Set([...setA, ...setB]); console.log(union); // 输出: Set(4) {1, 2, 3, 4} // 交集 const intersection = new Set([...setA].filter(x => setB.has(x))); console.log(intersection); // 输出: Set(2) {2, 3} // 差集 const difference = new Set([...setA].filter(x => !setB.has(x))); console.log(difference); // 输出: Set(1) {1} const userPermissions = new Set(['read', 'write']); const requiredPermissions = new Set(['read', 'delete']); // 交集:用户实际拥有的权限 const validPermissions = new Set([...userPermissions].filter(x => requiredPermissions.has(x))); console.log(validPermissions); // Set { 'read' } // 差集:缺失的权限 const missingPermissions = new Set([...requiredPermissions].filter(x => !userPermissions.has(x))); console.log(missingPermissions); // Set { 'delete' }
- Data Subscription and Deduplication
When dynamically managing subscribers (e.g., event listeners), Set is a highly efficient choice.
const subscribers = new Set(); function subscribe(listener) { subscribers.add(listener); // 确保唯一 } function notify(data) { subscribers.forEach(listener => listener(data)); } // 示例 subscribe(data => console.log(`Listener 1 received: ${data}`)); subscribe(data => console.log(`Listener 2 received: ${data}`)); notify('Event fired'); // 输出: // Listener 1 received: Event fired // Listener 2 received: Event fired
- Form Data Validation
Quickly check for duplicate form inputs.
const emailSet = new Set(); function addEmail(email) { if (emailSet.has(email)) { console.log('This email is already registered.'); } else { emailSet.add(email); console.log('Email registered successfully.'); } } // 示例 addEmail('test@example.com'); // Email registered successfully. addEmail('test@example.com'); // This email is already registered.
Leetcode Problems Using Se
(1) LeetCode 217: (Contains Duplicate)
Description: Check if an array contains any duplicates.
Key Concept: Use Set to check for duplicate elements.
var containsDuplicate = function(nums) { const set = new Set(); for (const num of nums) { if (set.has(num)) { return true; } set.add(num); } return false; };
(2) LeetCode 349: Intersection of Two Arrays
Description: Find the intersection of two arrays, ensuring no duplicate elements in the result.
Key Concept: Use Set to store unique values and perform set operations.
var intersection = function(nums1, nums2) { const set1 = new Set(nums1); const set2 = new Set(nums2); return [...set1].filter(num => set2.has(num)); };
(3) LeetCode 128: Longest Consecutive Sequence
Description: Find the longest consecutive elements sequence in an array, with a time complexity of O(n).
Key Concept: Use Set to store elements and optimize lookup.
var longestConsecutive = function(nums) { const set = new Set(nums); let maxLength = 0; for (const num of set) { if (!set.has(num - 1)) { // 只有当 num 是序列的起点时才检查 let currentNum = num; let currentLength = 1; while (set.has(currentNum + 1)) { currentNum += 1; currentLength += 1; } maxLength = Math.max(maxLength, currentLength); } } return maxLength; };