You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组重复对象检测与合并优化请求(附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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 14:35:35