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

TypeScript中API返回JSON格式转换求助:重组员工数据结构

TypeScript 实现API返回JSON格式转换

原API返回的是单个键值对组成的数组,每个元素仅包含员工的一个属性(empid/empName/gender/hobbie),需要按empName分组,将同属一个员工姓名的empid、gender、hobbie整合为带序列号的详情项,最终生成分组后的数组结构。

类型定义(确保TypeScript类型安全)

// 原始API返回的单个属性项类型
type EmployeeRawItem = 
  | { empid: number } 
  | { empName: string } 
  | { gender: string } 
  | { hobbie: string };

// 转换后的员工详情项类型
type EmployeeDetail = {
  serialNo: number;
  empid: number;
  gender: string;
  hobbie: string;
};

// 最终的分组员工类型
type FinalEmployee = {
  empName: string;
  empDetails: EmployeeDetail[];
};

转换函数实现

function transformEmployees(rawEmployees: EmployeeRawItem[]): FinalEmployee[] {
  const result: FinalEmployee[] = [];
  let currentGroup: FinalEmployee | null = null;
  let currentDetail: Partial<EmployeeDetail> = {};
  let serialCounter = 1;

  for (const item of rawEmployees) {
    // 遇到empName时,创建新的员工分组
    if ('empName' in item) {
      // 若存在未完成的员工详情,先将其加入上一个分组
      if (currentGroup && currentDetail.empid && currentDetail.gender && currentDetail.hobbie) {
        currentGroup.empDetails.push({
          ...currentDetail as EmployeeDetail,
          serialNo: serialCounter++
        });
        currentDetail = {};
      }
      // 初始化当前分组并加入结果数组
      currentGroup = {
        empName: item.empName,
        empDetails: []
      };
      result.push(currentGroup);
    } else {
      // 累积员工详情的各个属性
      if ('empid' in item) currentDetail.empid = item.empid;
      else if ('gender' in item) currentDetail.gender = item.gender;
      else if ('hobbie' in item) currentDetail.hobbie = item.hobbie;

      // 当empid、gender、hobbie都收集完成时,生成详情项加入当前分组
      if (currentGroup && currentDetail.empid && currentDetail.gender && currentDetail.hobbie) {
        currentGroup.empDetails.push({
          ...currentDetail as EmployeeDetail,
          serialNo: serialCounter++
        });
        currentDetail = {};
      }
    }
  }

  // 处理循环结束后剩余的未完成员工详情
  if (currentGroup && currentDetail.empid && currentDetail.gender && currentDetail.hobbie) {
    currentGroup.empDetails.push({
      ...currentDetail as EmployeeDetail,
      serialNo: serialCounter++
    });
  }

  return result;
}

测试代码

// 模拟API返回的原始数据
const rawEmployeeData: EmployeeRawItem[] = [
  { empid: 12345 },
  { empName: "John Doe" },
  { gender: "Male" },
  { hobbie: "Book" },
  { empid: 12347 },
  { gender: "Male" },
  { hobbie: "Gym" },
  { empid: 12346 },
  { empName: "Jill Doe" },
  { gender: "Female" },
  { hobbie: "Sport" }
];

// 执行转换
const finalEmployeeData = transformEmployees(rawEmployeeData);
// 打印转换结果
console.log(JSON.stringify(finalEmployeeData, null, 2));

转换结果说明

执行代码后会输出目标格式的JSON:

[
  {
    "empName": "John Doe",
    "empDetails": [
      {
        "serialNo": 1,
        "empid": 12345,
        "gender": "Male",
        "hobbie": "Book"
      },
      {
        "serialNo": 2,
        "empid": 12347,
        "gender": "Male",
        "hobbie": "Gym"
      }
    ]
  },
  {
    "empName": "Jill Doe",
    "empDetails": [
      {
        "serialNo": 3,
        "empid": 12346,
        "gender": "Female",
        "hobbie": "Sport"
      }
    ]
  }
]

(如果需要每个分组内的序列号单独递增,可以把serialCounter移到currentGroup中,每个分组初始化时设为1,添加详情时自增即可)

内容的提问来源于stack exchange,提问作者Sundaresan.C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:43:25