在JavaScript開(kāi)發(fā)中,數(shù)組作為最常用的數(shù)據(jù)結(jié)構(gòu)之一,幾乎無(wú)處不在。然而,Set
作為一種更高效且功能強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),卻常常被開(kāi)發(fā)者忽視。隨著TC39 Set提案中新增方法的引入,Set
的功能得到了進(jìn)一步擴(kuò)展,使其在處理數(shù)據(jù)集合時(shí)更加靈活和高效。本文將深入探討Set
的起源、核心功能、新增方法以及其在實(shí)際開(kāi)發(fā)中的應(yīng)用場(chǎng)景,幫助你全面掌握這一被低估的JavaScript利器。
· · ·
一、Set的起源與背景
1.1 ES6的革新:Set的誕生
Set
是在2015年隨著ECMAScript 6(ES6)的發(fā)布而引入的。在此之前,開(kāi)發(fā)者主要依賴數(shù)組來(lái)管理數(shù)據(jù)集合,但數(shù)組在處理唯一性和查找效率方面存在明顯短板:
- 重復(fù)值問(wèn)題:數(shù)組允許存儲(chǔ)重復(fù)值,導(dǎo)致唯一性檢查需要額外的邏輯。
- 低效的存在性檢查:查找數(shù)組中是否存在某個(gè)元素需要線性搜索(如
Array.includes
),時(shí)間復(fù)雜度為O(n),對(duì)于大型數(shù)據(jù)集來(lái)說(shuō)性能較差。
Set
的引入正是為了解決這些問(wèn)題。它提供了一種專門用于存儲(chǔ)唯一值的數(shù)據(jù)結(jié)構(gòu),并優(yōu)化了添加、刪除和查找操作,使代碼更簡(jiǎn)潔、更高效。
· · ·
二、Set的核心特性
2.1 什么是Set?
Set
是一種存儲(chǔ)唯一值的數(shù)據(jù)結(jié)構(gòu),這意味著它不會(huì)存儲(chǔ)重復(fù)的元素。以下是一個(gè)簡(jiǎn)單的示例:
const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(2); // 重復(fù)值,會(huì)被忽略
console.log(mySet); // 輸出: Set(2) { 1, 2 }
Set
可以存儲(chǔ)任何類型的值,包括原始類型和對(duì)象:
const mixedSet = new Set([1, 'hello', { key: 'value' }, true]);
console.log(mixedSet); // 輸出: Set(4) { 1, 'hello', { key: 'value' }, true }
2.2 Set的常見(jiàn)應(yīng)用場(chǎng)景
- 存在性檢查:高效判斷某個(gè)值是否存在于集合中。
- 數(shù)據(jù)集合操作:如并集、交集、差集等。
· · ·
三、Set的基本方法
3.1 add(value)
向Set
中添加一個(gè)值(如果值已存在,則忽略):
const mySet = new Set();
mySet.add(1);
mySet.add(2);
console.log(mySet); // 輸出: Set(2) { 1, 2 }
3.2 delete(value)
從Set
中刪除指定的值:
mySet.delete(1);
console.log(mySet); // 輸出: Set(1) { 2 }
3.3 has(value)
檢查Set
中是否存在某個(gè)值:
console.log(mySet.has(2)); // 輸出: true
console.log(mySet.has(3)); // 輸出: false
3.4 size
返回Set
中元素的數(shù)量:
console.log(mySet.size); // 輸出: 1
3.5 clear()
清空Set
中的所有元素:
mySet.clear();
console.log(mySet.size); // 輸出: 0
3.6 遍歷Set
Set
是可迭代的,可以通過(guò)for...of
或forEach
進(jìn)行遍歷:
const mySet = newSet([1, 2, 3]);
for (const value of mySet) {
console.log(value);
}
// 輸出:
// 1
// 2
// 3
mySet.forEach(value =>console.log(value));
// 輸出:
// 1
// 2
// 3
· · ·
四、Set的進(jìn)階功能:TC39提案新增方法
TC39提案為Set
引入了多個(gè)新方法,使其在處理集合操作時(shí)更加高效和直觀。
4.1 union
使用場(chǎng)景:合并兩個(gè)集合,去除重復(fù)值。
const viewedRecommendations = new Set([301, 302, 303]);
const topSelling = new Set([303, 304, 305]);
const combinedRecommendations = viewedRecommendations.union(topSelling);
console.log(combinedRecommendations); // 輸出: Set(5) { 301, 302, 303, 304, 305 }
4.2 intersection
使用場(chǎng)景:查找兩個(gè)集合的交集。
const promotionProducts = new Set([401, 402, 403]);
const viewedProducts = new Set([402, 403, 404]);
const productsToHighlight = promotionProducts.intersection(viewedProducts);
console.log(productsToHighlight); // 輸出: Set(2) { 402, 403 }
4.3 difference
使用場(chǎng)景:計(jì)算兩個(gè)集合的差集。
const viewedProducts = new Set([501, 502, 503]);
const cartProducts = new Set([503]);
const notInCart = viewedProducts.difference(cartProducts);
console.log(notInCart); // 輸出: Set(2) { 501, 502 }
4.4 symmetricDifference
使用場(chǎng)景:查找兩個(gè)集合的對(duì)稱差集。
const warehouseA = new Set([601, 602, 603]);
const warehouseB = new Set([603, 604, 605]);
const uniqueToEachWarehouse = warehouseA.symmetricDifference(warehouseB);
console.log(uniqueToEachWarehouse); // 輸出: Set(4) { 601, 602, 604, 605 }
4.5 isSupersetOf 和 isSubsetOf
使用場(chǎng)景:檢查一個(gè)集合是否包含另一個(gè)集合。
const inventory = new Set([801, 802, 803, 804]);
const cart = new Set([802, 803]);
console.log(inventory.isSupersetOf(cart)); // true
console.log(cart.isSubsetOf(inventory)); // true
4.6 isDisjointFrom
使用場(chǎng)景:檢查兩個(gè)集合是否沒(méi)有交集。
const restrictedPaymentMethods = new Set(['Paypal', 'Credit Card']);
const userPaymentMethod = new Set(['Gift Card']);
if (userPaymentMethod.isDisjointFrom(restrictedPaymentMethods)) {
console.log('Method not allowed');
} // Method not allowed
· · ·
五、Set與數(shù)組的性能對(duì)比
5.1 時(shí)間復(fù)雜度
Set
在添加、刪除和查找操作上的時(shí)間復(fù)雜度為O(1),而數(shù)組的這些操作通常需要O(n)。對(duì)于大型數(shù)據(jù)集,Set
的性能優(yōu)勢(shì)尤為明顯。
5.2 適用場(chǎng)景
- 使用Set:當(dāng)需要快速查找、去重或頻繁添加/刪除元素時(shí)。
- 使用數(shù)組:當(dāng)需要按索引訪問(wèn)元素或維護(hù)元素順序時(shí)。
· · ·
六、總結(jié)
Set
作為JavaScript中一種強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),在處理唯一值集合時(shí)表現(xiàn)出色。隨著TC39提案新增方法的引入,Set
的功能得到了進(jìn)一步擴(kuò)展,使其在并集、交集、差集等操作中更加高效。如果你經(jīng)常使用數(shù)組并希望優(yōu)化代碼性能,Set
無(wú)疑是一個(gè)值得嘗試的選擇。通過(guò)掌握Set
的核心功能和新增方法,你可以在開(kāi)發(fā)中更高效地處理數(shù)據(jù)集合,提升代碼質(zhì)量和性能。
· · ·
原文地址:https://medium.com/@olivier.lelay/set-an-underrated-power-of-javascript-a53aa712d464?source=rss------javascript_tips-5
該文章在 2025/5/10 18:27:37 編輯過(guò)