对象键值唯一性去重本质是利用JS对象或Map的键唯一性,将数组元素转为key存入,时间复杂度O(n),远优于filter+indexOf的O(n²),适合大量基本类型或对象数组按字段去重。

用对象键值唯一性去重,本质是把数组元素转成字符串作 key 存进普通对象或 Map,靠 JS 对象属性名天然不重复的特性筛掉重复项。它适合大量基本类型数据(如数字、字符串),执行快、内存可控,比 filter + indexOf 的 O(n²) 效率高得多。
为什么对象键值法适合大量数据
对象内部用哈希表实现属性查找,单次存取接近 O(1),整体时间复杂度约 O(n)。而 indexOf 每次都要从头遍历,10 万条数据时可能触发百万级比较。对象法只需一次遍历 + 一次属性写入判断,实测在 50 万量级仍稳定在毫秒级。
基础写法:用普通对象做 hash 表
适用于纯数字、字符串、布尔值等可安全转字符串的类型:
- 用空对象
{}当“记录本”,每遇到一个元素就检查它是否已作为 key 存在 - 存在则跳过;不存在则设为
true并推入结果数组 - 注意:
obj[item]会把0、""、false等 falsy 值误判,应改用hasOwnProperty或in操作符
示例代码:
const obj = {};
const result = [];
for (const item of arr) {
if (!obj.hasOwnProperty(item)) {
obj[item] = true;
result.push(item);
}
}
// result → [1, "1", 2, "a", 0]
升级写法:用 Map 替代普通对象
解决普通对象的两个硬伤:无法区分 1 和 "1",且不能用对象/数组当 key:
-
Map支持任意类型作 key,且严格按===判断相等,不会自动类型转换 - 对大量数据,
Map的插入和查询性能更稳定,内存管理也更优 - 写法更清晰:用
map.has(key)和map.set(key, value)
示例代码:
const arr = [1, "1", 2, 2, {}, {}];const map = new Map();
const result = [];
for (const item of arr) {
if (!map.has(item)) {
map.set(item, true);
result.push(item);
}
}
// result → [1, "1", 2, {}, {}](两个空对象都保留,因引用不同)
处理对象数组:按指定字段去重
如果数组里是对象,比如 [{id: 1, name: "A"}, {id: 1, name: "B"}],想按 id 去重,就不能直接用对象或 Map 存整个对象,而要提取唯一标识字段:
- 遍历中取
item.id作为 key,存进 Map 或对象 - 只在该 id 第一次出现时保留对应对象
- 这样既保持了原对象结构,又避免了深比较开销
示例代码(按 id 去重):
const users = [{id: 1, name: "A"}, {id: 2, name: "B"}, {id: 1, name: "C"}];const seen = new Map();
const uniqueUsers = [];
for (const user of users) {
if (!seen.has(user.id)) {
seen.set(user.id, true);
uniqueUsers.push(user);
}
}
// uniqueUsers → [{id: 1, name: "A"}, {id: 2, name: "B"}]


















