Set 和 Array 是 JavaScript 中两种不同的数据结构,各有其特点和适用场景。
核心区别对比
特性 | Set | Array |
---|---|---|
元素唯一性 | 自动去重 | 允许重复元素 |
元素顺序 | 插入顺序 | 索引顺序 |
查找性能 | O(1) | O(n) |
API复杂度 | 较简单 | 较丰富 |
内存占用 | 通常更大 | 通常更小 |
初始化 | new Set([iterable]) | [] 或 new Array(length) |
最佳实践指南
1. 使用 Set 的场景
当需要保证元素唯一性时:
// 去除数组重复项
const uniqueArray = [...new Set(duplicateArray)];
// 检查唯一性比数组高效
const tags = new Set();
tags.add('javascript');
if (!tags.has('typescript')) {
tags.add('typescript');
}
当需要快速查找时:
// 查找性能对比
const bigSet = new Set(hugeArray); // 初始化O(n)
bigSet.has(item); // O(1)
// 数组需要遍历
hugeArray.includes(item); // O(n)
2. 使用 Array 的场景
当需要维护元素顺序和索引时:
// 按索引访问
const users = ['Alice', 'Bob', 'Charlie'];
console.log(users[1]); // 'Bob'
// 需要丰富数组方法时
const filtered = users.filter(u => u.startsWith('A'));
当需要元素重复时:
// 允许重复的集合
const surveyAnswers = ['yes', 'no', 'yes', 'yes'];
3. 转换与协作
Set → Array:
const set = new Set([1, 2, 3]);
const array = [...set]; // 或 Array.from(set)
Array → Set:
const array = [1, 1, 2, 3];
const set = new Set(array); // 自动去重
4. 性能考量
// 测试查找性能
const largeData = Array(1000000).fill().map((_, i) => i);
// Array.includes
console.time('Array');
largeData.includes(999999);
console.timeEnd('Array'); // ~5ms
// Set.has
const largeSet = new Set(largeData);
console.time('Set');
largeSet.has(999999);
console.timeEnd('Set'); // ~0.01ms
5. 现代ES6+实践
使用 Set 进行集合运算:
// 并集
const union = new Set([...setA, ...setB]);
// 交集
const intersection = new Set([...setA].filter(x => setB.has(x)));
// 差集
const difference = new Set([...setA].filter(x => !setB.has(x)));
使用 Array 进行复杂操作:
// 链式操作
const result = bigArray
.filter(x => x > 10)
.map(x => x * 2)
.reduce((sum, x) => sum + x, 0);
选择建议
-
需要保证唯一性? → 选择 Set
-
需要快速查找? → 选择 Set
-
需要维护顺序/索引? → 选择 Array
-
需要丰富的数据操作方法? → 选择 Array
-
内存敏感场景? → 测试比较两者实际内存占用
总结
Set 和 Array 不是相互替代的关系,而是互补的数据结构。在实际开发中:
-
优先使用 Set 处理需要唯一性保证或频繁查找的场景
-
优先使用 Array 处理需要顺序访问或复杂转换的场景
-
两者可以互相转换,根据操作需求灵活选择最适合的结构