新 JavaScript Set 方法

新的 JavaScript Set 方法即将到来!自 Firefox 127 起,这些方法在大多数主流浏览器引擎中都可用,这意味着您不需要使用 polyfill 就能让它们在任何地方都能使用

本文适合初学 JavaScript 中的 Set 并希望了解如何使用这些新 JavaScript 方法的读者阅读。我将通过基本示例强调使用这些方法的一些优势,以说明为什么您可能会选择这些方法而不是构建自己的实现。

Set 方法有哪些新特性?

对于那些需要简要说明的读者,以下是支持跨浏览器的新方法的要点:

  • intersection() 返回一个新集合,其中包含本集合和给定集合中的元素。union() 返回一个新集合,其中包含此集合和给定集合中的所有元素。
  • difference() 返回一个新集合,其中包含此集合中的元素,但不包含给定集合中的元素。
  • symmetricDifference() 返回一个新集合,其中元素在任一集合中,但不在两个集合中。
  • isSubsetOf() 返回一个布尔值,表示某个集合的所有元素是否都在某个特定集合中。
  • isSupersetOf() 返回一个布尔值,表示一个集合的所有元素是否都在一个特定集合中。
  • isDisjointFrom() 返回一个布尔值,表示此集合是否与某个特定集合没有共同元素。

如果您在阅读(或略读)上述列表后感到困惑,不用担心,我们将在下面的章节中介绍它们的作用。这些方法中的每一种都用于检查集合的内容与另一个特定集合的内容的比较情况。

什么是 JavaScript Set?

Set 与数组类似,只是每个值只能存储一次。例如,我们可以获取一个项目列表,将它们全部添加到一个集合中,然后检查集合的结果。右边的列表是左边 <ol> 列表的内容,只不过转换成了集合。我们从列表中删除了所有重复项,因为我们保证集合是唯一的:

在这样一个小例子中,这可能看起来没什么,但如果有一种内置方法来创建唯一的项目集合,那就真的很方便了,尤其是在数据量较大、数据类型和对象较为复杂的情况下。例如,您可以像下面这样向集合中添加元素:

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

与数组相比,检查元素是否在集合中的速度通常也更快,因此这适合需要关注大型数据集性能的用例。您还可以在现有集合的基础上组成具有特定逻辑属性的新集合,下面我们将举例说明。

我们将在下文中介绍所有新方法,但如果你想了解可以用 set 做的所有事情,请查看实例方法文档

两个 Set 的联合

如果你对集合不熟悉,这是一个很好的开头示例。通过联合,我们可以检查 “任一或两个 “集合中都有哪些元素。在下面的示例中,我们有两个列表,我们想创建第三个列表,其中包含两个列表中的所有项目,但不重复:

// 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,因此我们得到的是字符串集合,但如果考虑到集合可以包含数组或对象等数据类型,你就会明白这有多么强大。

这很有帮助,因为我们不需要任何自定义实现来删除重复、进行相等检查或其他比较。一旦我们在集合中拥有了元素,我们就知道它们都是唯一的,而 union 方法是一种优化的方法,可以将 “任一或两个 “集合中出现的(唯一)项组成第三个集合。

Set 交集

通过 Set 交集,我们可以检查两个集合中都有哪些元素出现,从而了解重叠的情况。在本例中,我们不用像上面的union那样将交集集显示为第三个列表,而是用它来突出显示 “仅同时出现在两个集合中 “的元素:

// 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";
  }
});

Set 对称差值

在了解差集之前,我们先来了解一下对称差集(symmetricDifference),它听起来可能很复杂,但希望下面的示例能解开这个谜团。对称差分的作用是让我们检查哪些元素在任一集合中,而不是同时在两个集合中。

const setNotBoth = set1.symmetricDifference(set2);

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

如果你对这一切都感到陌生,并且难以理解,那么请比较一下对称差分和相交的示例。你会发现 symmetricDifference方法的逻辑运算与intersection方法相反。

Set 差

通过集合差,我们可以检查哪些元素在一个集合中,而不在另一个集合中。在本例中,我们将创建两个新集合,而不是一个。第一个集合(set1only)是用 set1.difference(set2) 创建的,我们得到的是一个 “只有集合一 “的新集合。我们对新的集合 set2only 进行同样的操作,以找到在集合二中但不在第一个集合中的项目。对于每个列表,我们都可以使用用 difference 创建的集合来突出显示另一个列表中没有出现的列表项。

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";
  }
});

子集、超集和 “从 “不相交

我们可以探索的最后一个新方法和新概念是子集、超集和 “从……不相交 “方法。现在,你已经熟悉了返回新集合的集合操作。子集、超集和 “从不相干 “方法并不返回新集合,而是返回一个 Boolean,用于表示某些状态或逻辑检查。

我们可以查看的前两个是子集和超集。我们不突出显示列表项,而是使用一些语句或断言,如 “集合一是集合二的子集”。然后,我们根据检查结果在列表项中添加一些文本(TRUE/FALSE),如 if (set1.isSupersetOf(set2))

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

因此,通过子集,我们可以检查一个集合中的所有项目是否都出现在另一个集合中。而使用超集时,我们要做的恰恰相反,即查看一个集合是否包含了另一个集合中的所有项目,以及一些额外的项目。

我们要看的最后一个方法是 isDisjointFrom(),在这个方法中,我们可以找出两个集合是否没有共同元素。下面的第一个和第二个集合互不相交,因为它们有一个共同元素(”C”)。第三个集合与其他两个集合不相交,因为它与任何一个集合都没有共同元素:

摘要

希望你喜欢这篇关于Set方法的文章,以及为什么我认为集合是一个值得理解的有趣概念。你知道在实际例子中使用这些方法的不同方法吗?欢迎随时与我们联系,让我知道你的想法或我是否遗漏了什么!你应该为下一个项目做好准备了,下次再见!

阅读余下内容
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号