js用Map对象实现数组去重
时间: 2025-07-20 07:28:08 浏览: 3
<think>我们使用Map对象实现数组去重的思路是:利用Map的键唯一性,将数组元素作为Map的键,然后提取这些键组成新数组。
注意:Map的键可以是任意类型,因此可以处理各种类型的去重(包括对象引用,但注意对象引用是严格相等的,即不同对象即使内容相同也会被当作不同键)。
步骤:
1. 创建一个空的Map对象。
2. 遍历数组,将每个元素作为键添加到Map中(值可以任意,比如设为true)。
3. 使用Map的keys()方法获取所有键,然后使用Array.from()将键的迭代器转换为数组(或者使用展开运算符...)。
但是注意:Map的键的顺序是插入顺序,因此去重后的数组会保持原数组的顺序。
代码实现:
```javascript
function uniqueArray(arr) {
const map = new Map();
arr.forEach(item => {
// 如果已经存在相同的键,则跳过,否则设置键值
// 这里我们不需要检查,因为Map的键是唯一的,重复设置同一个键只会更新值,不会新增键
map.set(item, true);
});
return Array.from(map.keys());
}
// 示例
const arr = [1, 2, 2, 'a', 'a', {a:1}, {a:1}, [1,2], [1,2]];
console.log(uniqueArray(arr));
// 输出: [1, 2, "a", {a:1}, {a:1}, [1,2], [1,2]]
// 注意:两个{a:1}和两个[1,2]都是不同的对象(引用不同),所以都会被保留
// 如果需要根据内容去重对象(即内容相同的对象视为相同),则不能直接使用Map,因为Map是严格相等(引用)。
// 但本问题要求使用Map,所以这里只按照引用去重。
```
另一种写法(使用循环构建):
```javascript
function uniqueArray(arr) {
const map = new Map();
const result = [];
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
map.set(arr[i], true);
result.push(arr[i]);
}
}
return result;
}
```
注意:上述两种方法在结果顺序上是一致的,都是按照第一次出现的顺序。
但是,如果数组中有NaN,需要注意:Map认为NaN等于NaN(这是Map和Set的特性,而普通对象中NaN会被转为字符串,且无法区分),所以可以正确处理NaN去重。
示例:
```javascript
console.log(uniqueArray([NaN, NaN, 1, 1, '1'])); // [NaN, 1, '1']
```
因此,使用Map实现数组去重可以正确处理各种类型,包括NaN。
§§相关问题§§
1. 使用Map对象实现数组去重与使用Set对象有何区别?
2. 为什么在Map对象中NaN被视为相同的键,而在普通对象中不行?
3. 如何修改上述去重函数以实现对象内容深比较去重(而非引用比较)?
4. 使用Map去重时,对于大数组的时间复杂度和空间复杂度是多少?
5. 在去重过程中,Map如何处理Symbol类型的元素?</think>在 JavaScript 中,使用 `Map` 对象实现数组去重是一种高效的方法,特别适合处理包含各种数据类型的数组(包括对象引用)。以下是实现代码:
```javascript
function uniqueWithMap(arr) {
const map = new Map();
const result = [];
for (const item of arr) {
// Map 的键可以是任意类型,包括对象引用
if (!map.has(item)) {
map.set(item, true); // 值可以是任意占位符
result.push(item);
}
}
return result;
}
// 使用示例
const arr = [1, 2, 2, 'a', 'a', {id:1}, {id:1}, [3], [3]];
console.log(uniqueWithMap(arr));
// 输出: [1, 2, "a", {id:1}, {id:1}, [3], [3]]
```
**关键特性说明**:
1. **引用类型处理**:`Map` 使用严格相等(`===`)比较键,因此不同对象即使内容相同也被视为不同
2. **顺序保留**:结果数组保持原始元素的出现顺序
3. **NaN 处理**:`Map` 能正确处理 `NaN` 去重(`NaN === NaN` 在 Map 中被视为相等)
4. **高效性**:`Map` 的查找操作 `has()` 时间复杂度为 O(1),整体算法为 O(n)
**对比其他方法**:
- 比 `Set` 更灵活:可中途修改或添加额外逻辑
- 比 `filter(indexOf)` 更高效:避免嵌套循环导致的 O(n²) 复杂度
- 比 `reduce` 更直观:代码可读性更高
**特殊值处理示例**:
```javascript
const testArr = [NaN, NaN, +0, -0, undefined, null, false, false];
console.log(uniqueWithMap(testArr));
// 输出: [NaN, 0, undefined, null, false] (+0/-0 被视为相同)
```
阅读全文
相关推荐


















