如何将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
相关产品推荐
相关产品推荐

