数组重复对象检测与合并优化请求(附JavaScript实现代码)
重复ID对象数组合并优化方案
问题描述
我有一个包含重复id的对象数组,每个对象的firstName、lastName和userId均不相同。需要检测其中的重复项,将重复对象的相关信息存入trainers数组并合并到第一个重复条目中。以下是我的原始实现,希望得到代码优化建议:
let data = [ { "id": 1, "details": { "title": "x detail" }, "userId": 146, "firstName": "me", "lastName": "testing" }, { "id": 2, "details": { "title": "x detail" }, "userId": 151, "firstName": "me", "lastName": "testing1" }, { "id": 1, "details": { "title": "x detail" }, "userId": 145, "firstName": "me", "lastName": "testing2" }, { "id": 3, "details": { "title": "x detail" }, "userId": 151, "firstName": "me", "lastName": "testing3" }, { "id": 4, "details": { "title": "x detail" }, "userId": 44, "firstName": "me", "lastName": "testing4" }, { "id": 1, "details": { "title": "x detail" }, "userId": 32, "firstName": "me", "lastName": "testing5" } ]; const dupes = [] const nonDupe = []; data.filter((o, index) => { if(dupes.find(i => i.id === o.id)) { o['trainers'] = [{ firstName:o.firstName, lastName:o.lastName, id:o.userId }] delete o.firstName; delete o.lastName; delete o.userId; nonDupe.push(o) return true } o['trainers'] = [{ firstName:o.firstName, lastName:o.lastName, id:o.userId }] delete o.firstName; delete o.lastName; delete o.userId; dupes.push(o) return false; }) let sortWithTrainers = []; dupes.map((val1, id1) =>{ nonDupe.map((val2, id2) =>{ if(val1.id == val2.id){ let merged = [...val1.trainers, ...val2.trainers] val1.trainers = merged sortWithTrainers.push(val1) }else{ sortWithTrainers.push(val1) } }) }) let nonDupeFinal = []; sortWithTrainers.map((val) =>{ if(nonDupeFinal.find(i => i.id === val.id)) { return true } nonDupeFinal.push(val) return false; }) console.log(nonDupeFinal)
优化方案
优化后的代码
const data = [ { "id": 1, "details": { "title": "x detail" }, "userId": 146, "firstName": "me", "lastName": "testing" }, { "id": 2, "details": { "title": "x detail" }, "userId": 151, "firstName": "me", "lastName": "testing1" }, { "id": 1, "details": { "title": "x detail" }, "userId": 145, "firstName": "me", "lastName": "testing2" }, { "id": 3, "details": { "title": "x detail" }, "userId": 151, "firstName": "me", "lastName": "testing3" }, { "id": 4, "details": { "title": "x detail" }, "userId": 44, "firstName": "me", "lastName": "testing4" }, { "id": 1, "details": { "title": "x detail" }, "userId": 32, "firstName": "me", "lastName": "testing5" } ]; // 提取生成trainer对象的复用逻辑 const createTrainer = ({ userId, firstName, lastName }) => ({ id: userId, firstName, lastName }); const mergedResult = Array.from( data.reduce((map, item) => { const existingItem = map.get(item.id); if (existingItem) { // 已有相同id的条目,追加trainer信息 existingItem.trainers.push(createTrainer(item)); } else { // 首次出现的id,构建新条目并初始化trainers数组 const newItem = { ...item, trainers: [createTrainer(item)] }; // 删除不需要保留的个人信息字段 delete newItem.userId; delete newItem.firstName; delete newItem.lastName; map.set(item.id, newItem); } return map; }, new Map()) .values() ); console.log(mergedResult);
优化细节说明
- 降低时间复杂度:原代码中多次使用
find和嵌套map,时间复杂度为O(n²);改用Map存储已处理条目,查找和插入操作均为O(1),整体时间复杂度降至O(n),数据量大时性能提升显著。 - 简化逻辑流程:通过
reduce一次遍历完成分组、trainers数组构建和字段清理,无需多个中间数组(如dupes、nonDupe),代码更紧凑易读。 - 保持数据不可变性:原代码直接修改原对象,优化后通过扩展运算符
{...item}创建新对象,避免意外修改原始数据,减少潜在bug。 - 逻辑复用:提取
createTrainer函数统一处理trainer对象的生成,后续若trainer结构调整,只需修改这一处即可,提升代码可维护性。
内容的提问来源于stack exchange,提问作者CodeBug
相关产品推荐
相关产品推荐

