javascript对象数组按多字段去重需构造唯一key保留首次项:推荐map+json.stringify([a,b]),兼容方案用reduce+findindex,封装函数支持传入字段名,嵌套字段需deepget处理,注意值类型统一。

JavaScript 对象数组按多字段组合去重,核心思路是把多个字段的值拼成一个唯一标识(key),再用 Map 或 Set 去重。关键不是“删重复项”,而是“保留首次出现的项”。
用 Map + 字符串 key 实现(推荐)
适合字段值类型较简单(字符串、数字、布尔值),且顺序固定的情况。
- 遍历数组,对每个对象提取目标字段(如 name 和 age),拼成唯一字符串 key,例如
obj.name + '|' + obj.age - 用 Map 缓存已见过的 key;只当 key 未存在时,才把当前对象推入结果数组并记录 key
- 注意:字段值含
|或其他特殊字符时,建议用 JSON.stringify([a, b]) 更稳妥
示例代码:
const arr = [
{ name: 'Alice', age: 25, city: 'Beijing' },
{ name: 'Bob', age: 30, city: 'Shanghai' },
{ name: 'Alice', age: 25, city: 'Guangzhou' }, // 与第1项 name+age 相同
{ name: 'Alice', age: 26, city: 'Beijing' }
];
const unique = [];
const seen = new Map();
for (const item of arr) {
const key = JSON.stringify([item.name, item.age]); // 多字段组合为数组再序列化
if (!seen.has(key)) {
seen.set(key, true);
unique.push(item);
}
}
// unique => 前、三、四项(去掉了重复 name+age 的第三项)
用 reduce + findIndex(兼容老环境)
不依赖 Map,适合需要支持 IE 的场景,但性能略低(O(n²))。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用 reduce 累积结果数组
- 每轮用 findIndex 检查当前项的多字段组合是否已在结果中出现过
- 判断逻辑写在 findIndex 的回调里,比如
r.name === cur.name && r.age === cur.age
封装成可复用函数
把字段名作为参数传入,提升复用性:
function uniqueByKeys(arr, keys) {
const seen = new Set();
return arr.filter(item => {
const key = keys.map(k => item[k]).join('|');
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
// 使用:uniqueByKeys(arr, ['name', 'age'])
⚠️ 注意:该版本假设字段值不含 |;更健壮的做法仍是用 JSON.stringify(keys.map(k => item[k])) 生成 key。
处理嵌套字段或动态路径
如果要去重的字段是嵌套的(如 user.profile.id),可用 Lodash 的 get 或自己写个安全取值函数:
- 先定义路径数组,如
['user', 'profile', 'id'] - 写一个
deepGet(obj, path)工具函数,避免访问undefined.xxx报错 - 再把 deepGet 结果参与 key 构建
不复杂但容易忽略细节:字段值类型要一致(比如后端可能返回字符串 "25" 和数字 25),建议统一转字符串或提前标准化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










