目录
新的JavaScript Set方法即将到来! 从Firefox 127开始,这些方法在大多数主要的浏览器引擎中都可用,这意味着您不需要polyfill来使它们在任何地方都能工作。
对于刚接触JavaScript中的Set并希望了解如何使用这些新的JavaScript方法的人来说,本文是一本很好的读物。 我将通过基本示例来强调使用这些方法的一些优点,以说明为什么您可能会使用这些方法而不是构建自己的实现。
Set方法中有哪些新增功能?
对于那些正在寻找TL;DR的人,以下是具有跨浏览器支持的新方法的要点:
- intersection()返回一个新集合,其中包含此集合和给定集合中的元素。
- union()返回一个新集合,其中包含此集合中的所有元素和给定的集合。
- difference()返回一个新集合,该集合中有元素,但不在给定集合中。
- symmetricDifference()返回一个新集合,其中任一组都有元素,但不能同时在两个集合中都有元素。
- isSubsetOf()返回一个布尔值,指示集合的所有元素是否都在特定集合中。
- isSupersetOf()返回一个布尔值,指示集合的所有元素是否都在特定集合中。
- isDisjointFrom()返回一个布尔值,指示此集合是否与特定集合没有共同的元素。
如果您已阅读(或略读)上述列表并感到困惑,请不要担心,我们将在以下各节中描述它们的作用。 这些方法中的每一种都用于检查集合的内容与另一个特定集合的内容进行比较。
什么是JavaScript Set?
集合类似于Array,不同之处在于每个值只能存储一次。 例如,我们可以获取一个项目列表,将它们全部添加到一个集合中,然后检查该集合的结果。右边的列表是左边的列表的<ol>内容,但已转换为集合。 我们已从列表中删除所有重复项,因为我们可以保证一组是唯一的:
在像这样的小示例中,这可能看起来并不多,但是拥有一种内置的方法来创建独特的项目集合确实非常方便,尤其是在更大的数据和更复杂的数据类型和对象上。 例如,假设您可以向集合添加元素,如下所示:
const dogs = new Set();
const yoshi = { name: "Yoshi", personality: "Friendly" };
dogs.add(yoshi);
检查元素是否在集合中而不是在数组中通常也更快,因此这适用于需要关注较大数据集中性能的用例。您还可以根据现有集合编写具有特定逻辑属性的新集合,我们将在下面查看其中的一些示例。
我们将在下面介绍所有新方法,但如果您想了解可以使用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方法是制作出现在“一个或两个”集合中的第三组(唯一)项的优化方法。
设置交叉点
通过集合交集,我们可以检查两个集合中都出现了哪些元素,以查看重叠是什么。 在此示例中,我们可以使用它来突出显示“仅两个集合”的元素,而不是像上面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";
}
});
设置对称差值
在我们研究差异之前,让我们看看symmetricDifference,其听起来很复杂,但希望下面的例子能揭开这个神秘面纱。 对称差的作用是让我们检查哪些元素在任一组中,但不能检查两者中。
const setNotBoth = set1.symmetricDifference(set2);
allListItems.forEach((item) => {
if (setNotBoth.has(item.textContent)) {
item.className = "match";
}
});
如果这是全新的,并且您难以理解,请将对称差异与交叉点示例进行比较。您应该看到该symmetricDifference方法执行与intersection相反的逻辑运算。
设置差异
通过集合差分,我们可以检查哪些元素在一个集合中,而哪些元素不在另一个集合中。在此示例中,我们将创建两个新集合,而不是一个集合。第一个(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";
}
});
子集、超集和不相交
我们可以探索的最后一种新方法和概念是子集、超集和“脱节”方法。到现在为止,您已经熟悉了返回新集合的集合操作。子集、超集和不相交的方法不返回新集,而是返回一个布尔值,用于指示特定状态或逻辑检查。
我们可以查看的前两个是子集和超集。 我们没有突出显示列表项,而是有一些语句或断言,例如“集合1是集合2的子集”。 然后,我们根据检查的结果向列表项添加一些文本(TRUE/FALSE),例如if (set1.isSupersetOf(set2)):
if (set1.isSubsetOf(set2)) {
oneSubTwo.textContent += " [TRUE]";
} else {
oneSubTwo.textContent += " [FALSE]";
}
因此,对于子集,我们可以检查一个集合中的所有项目是否出现在另一个集合中。 对于超集,我们做的是相反的,看看一个集合是否包含另一个集合的所有项目,以及一些额外的项目。
我们要看的最后一种方法是isDisjointFrom(),我们可以找出两个集合是否没有共同的元素。下面的第一组和第二组彼此不相交,因为它们有一个共同的元素(“C”)。 第三组与其他两组不相交,因为它与任一组都没有共同的项目:
总结
我希望你喜欢这篇关于Set方法的文章,以及为什么我认为集合是一个有趣的概念。 您知道在实际示例中使用这些方法的不同方法吗? 请随时与我们联系,让我知道您的想法或我是否遗漏了什么!你应该为完成下一个项目全力以赴使用Set,所以下次见!
https://developer.mozilla.org/en-US/blog/javascript-set-methods/