小白也能懂的JavaScript新秘密:Set数据结构完全解析!

1. Set是什么?

Set,作为JavaScript中引入的一种新型数据结构,可以看作是一种集合,类似于数组,但具有一些独特的特性。最引人注目的特性之一是其成员的值是唯一的,即不允许重复值存在。这意味着你可以轻松地存储一组不同的元素,而不必担心重复。

ini 复制代码
const uniqueNumbers = new Set([1, 2, 3, 4, 4]);
console.log([...uniqueNumbers]); // [1, 2, 3, 4]

在上面的例子中,我们创建了一个Set实例uniqueNumbers,并通过传递一个包含重复元素的数组进行初始化。但是,由于Set的特性,最终我们得到的是一个包含唯一值的数组。

Set的独特之处不仅在于去重,它还提供了一系列便捷的方法来操作集合,例如添加、删除和检查元素的存在。

2. Set的基本用法

2.1 创建Set实例

要使用Set,首先需要创建一个Set实例。你可以通过new Set()来创建一个空的Set,也可以通过传递一个数组或其他可迭代对象进行初始化。

ini 复制代码
const colors = new Set(['red', 'green', 'blue']);

在上述例子中,我们创建了一个包含颜色名称的Set实例,用于演示接下来的基本用法。

2.2 添加、删除和判断元素

Set提供了简单而强大的方法来管理集合中的元素。

添加元素

使用add(value)方法可以向Set中添加元素。

css 复制代码
colors.add('yellow');
console.log([...colors]); // ['red', 'green', 'blue', 'yellow']

删除元素

使用delete(value)方法可以删除Set中的元素。

css 复制代码
colors.delete('green');
console.log([...colors]); // ['red', 'blue', 'yellow']

判断元素是否存在

使用has(value)方法可以检查Set中是否存在某个元素。

arduino 复制代码
console.log(colors.has('red')); // true
console.log(colors.has('green')); // false

2.3 遍历Set

Set提供了多种遍历方法,让你能够轻松检查集合中的所有元素。

css 复制代码
for (let color of colors) {
  console.log(color);
}

以上是Set的基本用法,它不仅仅可以帮助你管理不重复的数据,还能够优雅地进行各种操作。

3. Set的应用

3.1 去除数组重复元素

Set结合扩展运算符可以轻松去除数组的重复元素,是一种小巧却强大的应用。

c 复制代码
// 原始数组
const array = [3, 5, 2, 2, 5, 5];

// 使用 Set 数据结构去除数组中的重复元素
const uniqueArray = [...new Set(array)];

// 打印去重后的数组
console.log(uniqueArray); // [3, 5, 2]

在这个例子中,我们使用Set快速去除了数组array中的重复元素,得到了一个不含重复值的新数组uniqueArray

3.2 集合运算

Set在集合运算方面表现得非常出色,可以轻松实现并集、交集、差集等操作。

并集

javascript 复制代码
// 创建两个 Set,分别包含元素 [1, 2, 3] 和 [3, 4, 5]
const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);

// 使用展开运算符和 Set 构造函数创建一个新的 Set,包含 setA 和 setB 的并集
const union = new Set([...setA, ...setB]);

// 打印合并后的 Set
console.log(union); // Set {1, 2, 3, 4, 5}

交集

javascript 复制代码
// 创建两个 Set,分别包含元素 [1, 2, 3] 和 [3, 4, 5]
const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);

// 使用过滤器和 Set 构造函数创建一个新的 Set,包含 setA 和 setB 的交集
const intersect = new Set([...setA].filter((x) => setB.has(x)));

// 打印两个 Set 的交集
console.log(intersect); // Set {3}

解释:

  1. const setA = new Set([1, 2, 3]); - 创建一个 Set,包含元素 1, 2, 和 3。
  2. const setB = new Set([3, 4, 5]); - 创建另一个 Set,包含元素 3, 4, 和 5。
  3. [...setA].filter((x) => setB.has(x)) - 将 setA 转换为数组,然后使用 filter 方法过滤出在 setB 中也存在的元素,即交集。
  4. const intersect = new Set([...setA].filter((x) => setB.has(x))); - 使用 Set 构造函数创建一个新的 Set,其中包含 setA 和 setB 的交集。
  5. console.log(intersect); - 打印两个 Set 的交集,结果为 Set {3},即 setA 和 setB 共有的元素。

差集

javascript 复制代码
// 创建两个 Set,分别包含元素 [1, 2, 3] 和 [3, 4, 5]
const setA = new Set([1, 2, 3]);
const setB = new Set([3, 4, 5]);

// 使用过滤器和 Set 构造函数创建一个新的 Set,包含 setA 和 setB 的差集
const difference = new Set([...setA].filter((x) => !setB.has(x)));

// 打印 setA 相对于 setB 的差集
console.log(difference); // Set {1, 2}

解释:

  1. const setA = new Set([1, 2, 3]); - 创建一个 Set,包含元素 1, 2, 和 3。
  2. const setB = new Set([3, 4, 5]); - 创建另一个 Set,包含元素 3, 4, 和 5。
  3. [...setA].filter((x) => !setB.has(x)) - 将 setA 转换为数组,然后使用 filter 方法过滤出在 setB 中不存在的元素,即 setA 相对于 setB 的差集。
  4. const difference = new Set([...setA].filter((x) => !setB.has(x))); - 使用 Set 构造函数创建一个新的 Set,其中包含 setA 相对于 setB 的差集。
  5. console.log(difference); - 打印 setA 相对于 setB 的差集,结果为 Set {1, 2},即 setA 中存在但 setB 中不存在的元素。

这些集合运算可以让你在处理数据时更加灵活,特别是在处理多个集合的情况下。

3.3 同步改变原Set结构

如果你想在遍历操作中同步改变原来的Set结构,可以使用映射方法或Array.from方法。

方法一:映射方法

dart 复制代码
// 创建一个 Set,包含元素 [1, 2, 3]
let set = new Set([1, 2, 3]);

// 使用映射和 Set 构造函数创建一个新的 Set,其中包含原 Set 中每个元素乘以 2 的结果
set = new Set([...set].map((val) => val * 2));

// 打印新的 Set,其中包含原 Set 中每个元素乘以 2 的结果
console.log(set); // Set {2, 4, 6}

方法二:Array.from方法

javascript 复制代码
// 创建一个 Set,包含元素 [1, 2, 3]
let set = new Set([1, 2, 3]);

// 使用 Array.from 和 Set 构造函数创建一个新的 Set,其中包含原 Set 中每个元素乘以 2 的结果
set = new Set(Array.from(set, (val) => val * 2));

// 打印新的 Set,其中包含原 Set 中每个元素乘以 2 的结果
console.log(set); // Set {2, 4, 6}

这些应用场景展示了Set在实际编程中的威力,为开发者提供了更多处理数据集合的可能性。

在下一部分,我们将进一步探索Set的高级用法,助你更深入地理解和应用这一强大的JavaScript数据结构。

4. 注意事项

在使用Set的过程中,有一些注意事项值得我们关注,确保我们能够充分利用这一强大的数据结构。

4.1 NaN的处理

Set内部判断两个值是否相等的算法与精确相等运算符稍有不同,特别是在处理NaN时。

ini 复制代码
let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
console.log(set); // Set {NaN}

在上述例子中,我们向Set实例添加了两个NaN,但实际上它们被视为相等。这是因为在Set内部,两个NaN被认为是相等的。

4.2 对象的比较

两个对象总是不相等,即使它们的内容相同。

arduino 复制代码
let set = new Set();
set.add({});
console.log(set.size); // 1
set.add({});
console.log(set.size); // 2

在这个例子中,我们向Set中添加了两个空对象,由于两个对象不是精确相等,它们被视为两个不同的值。

4.3 Set的遍历顺序

Set的遍历顺序是按照插入顺序的,这一特性在某些场景下非常有用,比如保证回调函数列表按照添加顺序调用。

javascript 复制代码
const callbackList = new Set();
callbackList.add(() => console.log('Callback 1'));
callbackList.add(() => console.log('Callback 2'));
callbackList.add(() => console.log('Callback 3'));

for (let callback of callbackList) {
  callback();
}

在上述例子中,回调函数将按照它们被添加的顺序被调用。

结语

在使用Set时,我们需要注意其对NaN的处理、对象比较以及遍历顺序等特性,以确保我们的代码行为符合预期。Set作为JavaScript中强大的数据结构之一,为我们处理不重复值的场景提供了便捷而高效的解决方案。通过充分了解这些注意事项,我们能够更好地运用Set,提升编码效率和质量。

相关推荐
贩卖纯净水.5 分钟前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家1 小时前
Vue 计算属性和监听器
前端·javascript·vue.js
前端啊龙1 小时前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js
一颗松鼠1 小时前
JavaScript 闭包是什么?简单到看完就理解!
开发语言·前端·javascript·ecmascript
小远yyds1 小时前
前端Web用户 token 持久化
开发语言·前端·javascript·vue.js
阿伟来咯~2 小时前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端2 小时前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱2 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
guai_guai_guai3 小时前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨3 小时前
在JS中, 0 == [0] 吗
开发语言·javascript