New JavaScript Set methods title. A vibrant gradient with a JavaScript logo in the bottom-left corner and a venn diagram in the top-right corner.

新的 JavaScript Set 方法

閱讀時間 5 分鐘

新的 JavaScript Set 方法即將推出!自 Firefox 127 起,這些方法已在大多數主流瀏覽器引擎中可用,這意味著您將無需 polyfill 來使其在所有地方都能工作

本文適合剛接觸 JavaScript Set 並想了解如何使用這些新 JavaScript 方法的人閱讀。我將重點介紹使用這些方法的一些優點,並提供基本示例,說明為什麼您可能需要使用它們而不是自己實現。

Set 方法有哪些新特性?

對於那些想要快速瞭解的人來說,以下是具有跨瀏覽器支援的新方法的要點:

  • intersection() 返回一個新的 Set,其中包含此 Set 和給定 Set 中的所有元素。
  • union() 返回一個新的 Set,其中包含此 Set 和給定 Set 中的所有元素。
  • difference() 返回一個新的 Set,其中包含此 Set 中但不在給定 Set 中的元素。
  • symmetricDifference() 返回一個新的 Set,其中包含任一 Set 中的元素,但不同時包含兩者。
  • isSubsetOf() 返回一個布林值,指示一個 Set 的所有元素是否在一個特定 Set 中。
  • isSupersetOf() 返回一個布林值,指示一個 Set 是否包含另一個 Set 的所有元素。
  • isDisjointFrom() 返回一個布林值,指示此 Set 是否與特定 Set 沒有共同元素。

如果您已閱讀(或瀏覽)以上列表但感到困惑,請不用擔心,我們將在後續章節中進行描述。這些方法都用於檢查 Set 的內容與另一個特定 Set 的內容相比如何。

什麼是 JavaScript Set?

Set 類似於 Array,但每個值只能儲存一次。例如,我們可以列出一系列專案,將它們全部新增到 Set 中,然後檢查 Set 的結果。右側的列表是左側 <ol> 列表的內容,但已轉換為 Set。我們已從列表中刪除了所有重複項,因為我們保證 Set 中的元素是唯一的。

在這樣的小例子中,這可能看起來沒什麼大不了的,但擁有一個內建的方法來建立唯一的專案集合非常方便,尤其是在處理大量資料和更復雜的資料型別和物件時。例如,可以像這樣向 Set 新增元素:

js
const dogs = new Set();
const yoshi = { name: "Yoshi", personality: "Friendly" };
dogs.add(yoshi);

通常,在 Set 中檢查元素是否存在也比在 Array 中快,因此這適用於需要關注大型資料集效能的用例。您還可以基於現有 Set 組合具有特定邏輯屬性的新 Set,我們將在下面看一些示例。

我們將在下面介紹所有新方法,但如果您想了解 Set 的所有功能,請檢視 例項方法文件。

兩個集合的並集

如果您不熟悉 Set,這是一個很好的入門示例。透過並集,我們可以檢查“任一或兩者” Set 中存在哪些元素。在下面的示例中,我們有兩個列表,我們想建立一個第三個列表,其中包含兩個列表中的所有專案,但沒有重複項。

js
// Create a union of both sets
const unionSet = set1.union(set2);

// List the items in the union
unionSet.forEach((item) => {
  const li = document.createElement("li");
  li.textContent = item;
  unionList.appendChild(li);
});

我們使用每個列表項的 HTML textContent,因此我們得到的是字串 Set,但您可以看到,如果我們考慮到 Set 可以包含陣列或物件等資料型別,這會多麼強大。

這很有幫助,因為我們不需要任何自定義實現來刪除重複項、執行相等性檢查或進行其他比較。一旦我們將元素放入 Set 中,我們就知道它們都是唯一的,而 union 方法是建立包含出現在“任一或兩者” Set 中的(唯一)專案的第三個 Set 的最佳化方式。

集合交集

透過 Set 交集,我們可以檢查兩個 Set 中共同存在的元素,以檢視重疊部分。在此示例中,我們不將交集 Set 顯示為第三個列表,就像我們之前對 union 所做的那樣,而是可以使用它來突出顯示“僅屬於這兩個 Set”的元素。

js
// Make the intersection set
const intersectionSet = set1.intersection(set2);

// Loop through lists and highlight if they're in the intersection
allListItems.forEach((item) => {
  if (intersectionSet.has(item.textContent)) {
    item.className = "match";
  }
});

集合對稱差集

在檢視差集之前,讓我們先看看 symmetricDifference,它聽起來可能很複雜,但希望下面的示例能使其變得簡單。對稱差集允許我們檢查哪些元素存在於任一 Set 中,但不包含兩者

js
const setNotBoth = set1.symmetricDifference(set2);

allListItems.forEach((item) => {
  if (setNotBoth.has(item.textContent)) {
    item.className = "match";
  }
});

如果這一切對您來說都是新的並且您正在努力理解,請將對稱差集交集示例進行比較。您應該會看到 symmetricDifference 方法執行的操作與 intersection 的邏輯操作相反。

集合差集

透過 Set 差集,我們可以檢查一個 Set 中存在但另一個 Set 中不存在的元素。對於這個例子,我們建立了兩個新 Set 而不是一個。第一個(set1only)是透過 set1.difference(set2) 建立的,我們得到的是一個包含“僅屬於 Set one”的新 Set。我們對新 Set set2only 做同樣的事情,以查詢屬於 Set two 但不屬於 Set one 的專案。對於每個列表,我們可以使用用 difference 建立的 Set 來突出顯示未出現在另一個列表中的列表項。

js
const set1only = set1.difference(set2);
const set2only = set2.difference(set1);

allListItems.forEach((item) => {
  if (set1only.has(item.textContent)) {
    item.className = "setOneMatch";
  } else if (set2only.has(item.textContent)) {
    item.className = "setTwoMatch";
  }
});

子集、超集和不相交集

最後要探索的新方法和概念是子集、超集和“不相交集”方法。現在,您已經熟悉了返回新 Set 的 Set 操作。子集、超集和不相交集方法不返回新 Set,而是返回一個 Boolean 值,以指示特定的狀態或邏輯檢查。

我們可以首先檢視**子集**和**超集**。我們不突出顯示列表項,而是有一些陳述或斷言,例如“Set one 是 Set two 的子集”。然後,我們根據諸如 if (set1.isSupersetOf(set2)) 之類的檢查結果,在列表項中新增一些文字(TRUE / FALSE)。

js
if (set1.isSubsetOf(set2)) {
  oneSubTwo.textContent += " [TRUE]";
} else {
  oneSubTwo.textContent += " [FALSE]";
}

因此,使用**子集**,我們可以檢查一個 Set 中的所有專案是否出現在另一個 Set 中。使用**超集**,我們做相反的事情,以檢視一個 Set 是否包含另一個 Set 的所有專案,以及一些額外的專案。

我們要看的最後一個方法是 isDisjointFrom(),我們可以用它來找出兩個 Set 是否**沒有共同元素**。下面的第一個和第二個 Set 不互斥,因為它們有一個共同的元素(“C”)。第三個 Set 與其他兩個 Set 不相交,因為它與任一 Set 都沒有共同的專案。

總結

希望您喜歡這篇關於 Set 方法的博文,以及為什麼我認為 Set 是一個有趣的概念。您知道在實際示例中有哪些不同的方法可以使用這些方法嗎?請隨時與我們聯絡,告訴我您的想法或我是否遺漏了什麼!您應該已經為下一個專案做好了 Set 的準備,下次再見!