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

React中合并对象数组并按唯一Email渲染表格的问题

问题

从API获取两个对象数组(候选人数据Candidates和职位空缺数据Jobopenings),尝试在表格中渲染时,用扩展运算符合并数组后出现同一Email对应多行的重复渲染问题。需要实现按唯一Email合并数组,使每个Email对应表格一行。

问题原因

直接用[...data.Candidates, ...data.Jobopenings]只是简单拼接两个数组,导致同一Email的条目(比如Pradeep的候选人数据和职位空缺数据)会被分别保留,渲染时自然出现重复行。

解决方案

通过按Email分组合并属性的方式处理数组:用一个中间对象存储每个Email对应的合并数据,遍历两个数组时将相同Email的属性合并,最后将对象转为数组即可得到去重且合并后的数据集。同时要修正表格的HTML结构(避免每个循环生成独立的<tbody>)。

修改后的代码

export default function App() {
  const [allData, setAllData] = useState([]);
  let data = {
    status: 'success',
    Candidates: [
      {
        Recruiter: 'Pradeep',
        Email: 'Pradeep@gmail.com',
        Total: 11,
        Hired: 2,
        interviewscheduled: 0,
        clientsubmitted: 1,
        Withdrawn: 0,
        Onhold: 5,
        inprocess: 0,
        Rejected: 1,
        Available: 0,
        tobeupdated: 2,
      },
      {
        Recruiter: 'Sudhir',
        Email: 'sudhir@gmail.com',
        Total: 6,
        Hired: 1,
        interviewscheduled: 0,
        clientsubmitted: 1,
        Withdrawn: 0,
        Onhold: 1,
        inprocess: 0,
        Rejected: 0,
        Available: 0,
        tobeupdated: 3,
      },
    ],
    Jobopenings: [
      {
        Recruiter: 'Pradeep',
        Email: 'Pradeep@gmail.com',
        jobopeningTotal: 4,
      },
      {
        Recruiter: 'Sudhir',
        Email: 'sudhir@gmail.com',
        jobopeningTotal: 7,
      },
      {
        Recruiter: 'Marry Scott',
        Email: 'marrys@hsc.com',
        jobopeningTotal: 1,
      },
    ],
  };

  useEffect(() => {
    // 创建映射对象,用Email作为唯一键
    const mergedMap = {};

    // 先处理候选人数据,初始化映射
    data.Candidates.forEach(item => {
      mergedMap[item.Email] = { ...item };
    });

    // 处理职位空缺数据,合并到已有条目或新增
    data.Jobopenings.forEach(item => {
      if (mergedMap[item.Email]) {
        // 合并属性,职位数据会覆盖候选人中同名属性(这里没有冲突)
        mergedMap[item.Email] = { ...mergedMap[item.Email], ...item };
      } else {
        // 新增没有候选人数据的职位条目
        mergedMap[item.Email] = { ...item };
      }
    });

    // 将映射转为数组
    const mergedData = Object.values(mergedMap);
    setAllData(mergedData);
  }, []);

  return (
    <div>
      <table className="table table-bordered rounded">
        <thead>
          <tr>
            <th scope="col">Recruiter Name</th>
            <th scope="col">Job Openings</th>
            <th scope="col">Hired Candidates</th>
            <th scope="col">Candidates</th>
            <th scope="col">Clients' Submissions</th>
            <th scope="col">Interviews Scheduled</th>
          </tr>
        </thead>
        <tbody>
          {allData?.map((eachItem) => {
            return (
              <tr key={eachItem.Email}>
                <td scope="row">{eachItem.Recruiter}</td>
                <td>{eachItem.jobopeningTotal || 0}</td>
                <td>{eachItem.Hired || 0}</td>
                <td>{eachItem.Total || 0}</td>
                <td>{eachItem.clientsubmitted || 0}</td>
                <td>{eachItem.interviewscheduled || 0}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

关键说明

  1. 合并逻辑:用mergedMap对象存储每个Email的合并数据,先存入候选人数据,再遍历职位数据合并到对应条目,确保同一Email只保留一条合并后的数据。
  2. HTML结构修正:将<tbody>从map循环中移出,避免生成多个tbody标签,符合标准表格结构。
  3. 默认值处理:在渲染表格单元格时添加|| 0,避免没有对应属性时显示undefined,优化视觉效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:25:22