一、Set基础
在 JavaScript 中,Set
是一种集合(Collection) 数据结构,用于存储唯一值 (不允许重复),并且可以高效地进行添加、删除、查询 等操作。它类似于数组(Array
),但成员的值都是唯一的,没有重复项。
1. Set 的基本特性
- 存储唯一值 :
Set
不会存储重复的值,如果尝试添加重复值,会被自动忽略。 - 无序存储 :
Set
中的元素没有索引,遍历顺序与插入顺序一致,但不支持索引访问(如set[0]
)。 - 可迭代 :可以使用
for...of
或forEach
遍历Set
中的元素。 - 支持任意数据类型 :可以存储
number
、string
、object
、function
等,但NaN
和undefined
也可以被存储。
2. 创建 Set
const mySet = new Set(); // 空 Set
const mySet2 = new Set([1, 2, 3, 4, 4, 5]); // 自动去重,最终存储 [1, 2, 3, 4, 5]
3. Set 的常用方法
方法 | 描述 | 示例 |
---|---|---|
add(value) |
添加一个值,返回 Set 本身(可链式调用) |
mySet.add(10).add(20) |
delete(value) |
删除某个值,返回 boolean (是否删除成功) |
mySet.delete(1) |
has(value) |
检查 Set 是否包含某个值,返回 boolean |
mySet.has(2) |
clear() |
清空 Set |
mySet.clear() |
size |
返回 Set 的元素个数(类似 Array.length ) |
mySet.size |
示例:
const set = new Set();
set.add(1); // Set { 1 }
set.add(2); // Set { 1, 2 }
set.add(2); // 重复值,被忽略
set.add("hello"); // Set { 1, 2, "hello" }
console.log(set.size); // 3
console.log(set.has(1)); // true
set.delete(1); // true
console.log(set.has(1)); // false
4. Set 的遍历方法
Set
是可迭代的,可以使用以下方式遍历:
**(1) for...of
循环**
const set = new Set([1, 2, 3]);
for (const item of set) {
console.log(item); // 1, 2, 3
}
**(2) forEach
方法**
set.forEach((value) => {
console.log(value); // 1, 2, 3
});
**(3) 转换成数组(Array.from
或 [...set]
)**
const arr = Array.from(set); // [1, 2, 3]
const arr2 = [...set]; // [1, 2, 3]
5. Set 的应用场景
**(1) 数组去重**
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)]; // [1, 2, 3, 4, 5]
**(2) 判断元素是否存在(比 Array.includes
更快)**
const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true
**(3) 存储非重复对象(需注意引用类型)**
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
const set = new Set([obj1, obj2, obj1]); // 存储 obj1 和 obj2(obj1 只存一次)
**(4) 数学集合运算(并集、交集、差集)**
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);
// 并集
const union = new Set([...setA, ...setB]); // Set {1, 2, 3, 4}
// 交集
const intersection = new Set([...setA].filter(x => setB.has(x))); // Set {2, 3}
// 差集(A - B)
const difference = new Set([...setA].filter(x => !setB.has(x))); // Set {1}
6. Set 与 Array 的区别
特性 | Set |
Array |
---|---|---|
唯一性 | 不允许重复值 | 允许重复值 |
索引访问 | 不支持 set[0] |
支持 arr[0] |
查找效率 | has() 是 O(1) |
includes() 是 O(n) |
顺序 | 插入顺序 | 索引顺序 |
方法 | add() / delete() |
push() / pop() |
7. 注意事项
-
NaN
在Set
中被认为是相同的值:const set = new Set(); set.add(NaN); set.add(NaN); // 只会存一个 NaN
-
Set
存储对象时,比较的是引用 而非值:const obj1 = { a: 1 }; const obj2 = { a: 1 }; set.add(obj1); set.add(obj2); // 会存储两个对象,因为引用不同
总结
Set
是一种存储唯一值 的集合,适用于去重、快速查找、集合运算等场景。- 主要方法:
add()
、delete()
、has()
、clear()
、size
。 - 遍历方式:
for...of
、forEach
、[...set]
。 - 相比数组,
Set
在去重和查找方面更高效,但不支持索引访问。
如果你需要存储不重复的值,并且希望高效地判断某个值是否存在,Set
是一个很好的选择!
二、349.两个数组的交集
给定两个数组
nums1
和nums2
,返回 它们的 输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4] 解释:[4,9] 也是可通过的
方法 1:使用 Set 去重 + 遍历查找
javascript
function intersection(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
const result = [];
for (const num of set1) {
if (set2.has(num)) {
result.push(num);
}
}
return result;
}
方法 2:使用 Set + Array.filter
javascript
function intersection(nums1, nums2) {
const set1 = new Set(nums1);
const set2 = new Set(nums2);
return [...set1].filter(num => set2.has(num));
}
方法 3:仅使用 Set + Array.includes(适用于小规模数据)
javascript
function intersection(nums1, nums2) {
const uniqueNums1 = [...new Set(nums1)];
return uniqueNums1.filter(num => nums2.includes(num));
}
总结
- 使用
Set
去重 是解决此类问题的关键。 - 遍历查找交集 时,
Set.has()
比Array.includes()
更高效(O(1) vs O(n))。 - 返回结果顺序不重要,因此直接返回过滤后的数组即可。
给你两个整数数组
nums1
和nums2
,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[4,9]
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
需要统计次数,就需要用上数组了。也可以用map 但还没复习到,后续会更新。
javascript
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersect = function(nums1, nums2) {
let hashs = new Array(1001).fill(0);
let result=[];
for(let i=0;i<nums1.length;i++){
hashs[nums1[i]]++;
}
for(let i=0;i<nums2.length;i++){
if(hashs[nums2[i]]>0) {
result.push(nums2[i]);
hashs[nums2[i]]--;
}
}
return result;
};