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

遍历JSON数组生成结构化对象时,时间条目误加至所有员工对象

问题:考勤条目被错误添加到所有员工对象中

我处理一组考勤JSON数据时遇到了问题:考勤条目确实被添加到了正确的日期和项目下,但所有员工对象的对应项目里都包含了其他员工的考勤条目,而不是只添加到所属员工的对象中。

我的处理逻辑是:

  • 遍历响应数据,为每位员工在employeeList中创建以姓名为键的Employee对象,同时收集所有项目到projectList
  • 把projectList添加到dateList的每个日期属性中
  • 将带项目列表的dateList赋值给每位员工的timeentries属性
  • 再次遍历响应,把考勤条目添加到对应员工、日期、项目的timecards数组中

我的代码

let employeeList = {};
let projectList = {};

let dateList = {
    "2023-02-26": {},
    "2023-02-27": {},
    "2023-02-28": {},
    "2023-03-01": {},
};

class Employee {
    constructor(name, qbid) {
        this.startdate = '2023-02-26';
        this.enddate = '2023-03-01';
        this.fname = "";
        this.lname = "";
        this.name = name;
        this.qbid = qbid;
        this.timeentries = [];
    }
}

function processData(res) {
    //create employee objects for each employee timeentry[155].value is a name text value "Last, First"
    res.data.forEach((timeentry) => {
        employeeList[timeentry[155].value] = new Employee(timeentry[155].value,timeentry[160].value);
    //add all projects to projectList obj.
        projectList[timeentry[18].value] = {
            projectname: timeentry[18].value,
            projectid: timeentry[17].value,
            timecards: []
        }
    });
//add projectList to each date in dateList
    for (key in dateList) {
        dateList[key] = projectList
    }
//add dateList with projectLists to employee.timeentries
    for (key in employeeList) {
        employeeList[key].timeentries = dateList;
    }
    
//add time entry objects to employee,date,project     
    res.data.forEach(timeentry => {
        employeeList[timeentry[155].value].timeentries[timeentry[23].value][timeentry[18].value].timecards.push(timeentry)
    })
}

最终生成的Employee对象示例

Last, First: {
     fname: 'First',
     lname: 'Last',
     timeentries: {
          2023-03-01: {
                project1:{
                     timecards:[JSON Object]
                     },
                project2:{
                     timecards:[JSON Object]
                     }
           },
           2023-03-02: {
                project1:{
                     timecards:[JSON Object]
                     },
                project2:{
                     timecards:[JSON Object]
                     }
           }
    }
}

问题原因

JavaScript中对象是引用类型,你的代码里犯了两个关键的引用复用错误:

  1. 把projectList直接赋值给dateList的每个日期属性——所有日期都指向同一个projectList对象,而非各自拥有独立的项目列表
  2. 把dateList直接赋值给每个员工的timeentries属性——所有员工的timeentries都指向同一个dateList对象

这意味着,当你给某一位员工的某个项目添加考勤条目时,实际上是在修改那个共享的projectList里的timecards数组,所有引用这个对象的员工都会看到这个变化。

解决思路

核心是为每个日期、每个员工创建独立的对象副本,而非复用同一个引用:

  1. 为dateList的每个日期生成独立的项目对象(每个项目的timecards都是新数组)
  2. 为每个员工的timeentries创建专属的日期-项目结构,确保员工间的对象互不关联

修正后的代码

let employeeList = {};
let projectList = {};

let dateList = {
    "2023-02-26": {},
    "2023-02-27": {},
    "2023-02-28": {},
    "2023-03-01": {},
};

class Employee {
    constructor(name, qbid) {
        this.startdate = '2023-02-26';
        this.enddate = '2023-03-01';
        this.fname = "";
        this.lname = "";
        this.name = name;
        this.qbid = qbid;
        this.timeentries = {}; // 改为对象类型,匹配dateList结构
    }
}

function processData(res) {
    // 第一步:收集员工和项目信息(避免重复创建)
    res.data.forEach((timeentry) => {
        const empName = timeentry[155].value;
        if (!employeeList[empName]) {
            employeeList[empName] = new Employee(empName, timeentry[160].value);
        }
        const projName = timeentry[18].value;
        if (!projectList[projName]) {
            projectList[projName] = {
                projectname: projName,
                projectid: timeentry[17].value,
                timecards: []
            };
        }
    });

    // 第二步:为每个员工创建独立的日期-项目结构
    for (const empName in employeeList) {
        const emp = employeeList[empName];
        emp.timeentries = {};
        for (const dateStr in dateList) {
            emp.timeentries[dateStr] = {};
            // 为每个项目创建独立对象,确保timecards数组不共享
            for (const projName in projectList) {
                emp.timeentries[dateStr][projName] = {
                    ...projectList[projName],
                    timecards: []
                };
            }
        }
    }
    
    // 第三步:添加考勤条目到对应员工、日期、项目
    res.data.forEach(timeentry => {
        const empName = timeentry[155].value;
        const dateStr = timeentry[23].value;
        const projName = timeentry[18].value;
        employeeList[empName].timeentries[dateStr][projName].timecards.push(timeentry);
    });
}

内容的提问来源于stack exchange,提问作者schteev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:54:56