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

如何将FormData/解析对象中的timeslots转换为结构化数组?

问题:将扁平结构的FormData/对象转换为嵌套的timeslots数组

初始问题

给定如下简化的FormData:

FormData {
  "id": "id1",
  "timeslots[0][start]": "2023-06-10",
  "timeslots[0][end]": "2023-06-09",
  "timeslots[1][start]": "2024-06-10",
  "timeslots[1][end]": "2024-06-09",
  ....
}

或已解析的扁平对象:

{
  id: "id1",
  "timeslots[0][start]": "2023-06-10",
  "timeslots[0][end]": "2023-06-09",
  "timeslots[1][start]": "2024-06-10",
  "timeslots[1][end]": "2024-06-09",
  ...
}

需要将其中的timeslots转换为数组,最终得到如下结构:

{
  id: "id1",
  timeslots:[
   { start: "2023-06-10", end: "2023-06-09" },
   { start: "2024-06-10", end: "2024-06-09" }
  ]
 }

已尝试的代码(未取得理想进展):

const timeslots = []
for (const [key, value] of Object.entries(body)) {
  if (key.startsWith('timeslots')) {
    const new_key = key.substring(13, key.length - 1)
    const slot = key.substring(10, 11)
    const tmp = { [new_key]: value, number: slot }
    timeslots.push(tmp)
    ...
  }
}

补充说明(问题扩展)

给定扩展后的扁平对象:

{
  id: "id1",

  "timeslots[0][start]": "2023-06-10",
  "timeslots[0][end]": "2023-06-09",
  "timeslots[0]disability[3]": "D3",
  "timeslots[0]disability[4]": "D4",

  "timeslots[1][start]": "2024-06-10",
  "timeslots[1][end]": "2024-06-09",
  "timeslots[1]disability[1]": "D1",
  "timeslots[1]disability[5]": "D5",
  ...
}

需修改方案以得到如下目标结构:

{
  id: "id1",
  timeslots:[
   { start: "2023-06-10", end: "2023-06-09", disability: ['D3', 'D4'] },
   { start: "2024-06-10", end: "2024-06-09", disability: ['D1', 'D5'] }
  ]
 }

解决方案

1. 初始问题的简洁实现

通过正则表达式匹配键名中的索引和属性,遍历一次即可构建嵌套结构:

const transformData = (rawData) => {
  const result = { id: rawData.id, timeslots: [] };
  
  for (const [key, value] of Object.entries(rawData)) {
    // 匹配 timeslots[索引][属性] 格式的键
    const match = key.match(/^timeslots\[(\d+)\]\[(\w+)\]$/);
    if (match) {
      const index = parseInt(match[1]);
      const prop = match[2];
      
      // 初始化当前索引的timeslot对象(如果不存在)
      if (!result.timeslots[index]) {
        result.timeslots[index] = {};
      }
      // 给对应属性赋值
      result.timeslots[index][prop] = value;
    }
  }
  
  return result;
};

2. 扩展问题的适配实现

调整正则规则,区分普通属性和disability数组字段,完成多类型数据的转换:

const transformExtendedData = (rawData) => {
  const result = { id: rawData.id, timeslots: [] };
  
  for (const [key, value] of Object.entries(rawData)) {
    // 匹配两种格式:timeslots[索引][属性] 或 timeslots[索引]disability[子索引]
    const propMatch = key.match(/^timeslots\[(\d+)\]\[(\w+)\]$/);
    const disabilityMatch = key.match(/^timeslots\[(\d+)\]disability\[\d+\]$/);
    
    if (propMatch) {
      const index = parseInt(propMatch[1]);
      const prop = propMatch[2];
      
      if (!result.timeslots[index]) {
        result.timeslots[index] = { disability: [] }; // 初始化时默认创建disability数组
      }
      result.timeslots[index][prop] = value;
    } else if (disabilityMatch) {
      const index = parseInt(disabilityMatch[1]);
      
      if (!result.timeslots[index]) {
        result.timeslots[index] = { disability: [] };
      }
      // 将disability值推入对应数组
      result.timeslots[index].disability.push(value);
    }
  }
  
  return result;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:20:42