
本教程旨在指导开发者如何将具有扁平化、括号式键名(如`timeslots[0][start]`)的JavaScript对象或FormData结构,转换为更易于操作的嵌套数组对象。文章将详细介绍两种主要转换方法:一种适用于简单的数组对象结构,利用`filter`、`map`和`reduce`进行链式处理;另一种则针对包含多层嵌套数组(如`disability`)的复杂场景,采用迭代和正则表达式匹配构建目标结构,并提供详细代码示例和最佳实践。
在Web开发中,尤其是在处理表单提交数据时,我们经常会遇到一种扁平化的键名结构,例如FormData对象或从后端接收到的JSON对象。这些键名通常采用类似key[index][property]的格式来表示数组或嵌套对象,如timeslots[0][start]。尽管这种格式便于某些后端框架处理,但在JavaScript前端进行数据操作时,我们通常更倾向于使用标准的嵌套数组和对象结构,例如:
{
id: "id1",
timeslots: [
{ start: "2023-06-10", end: "2023-06-09" },
{ start: "2024-06-10", end: "2024-06-09" }
]
}本文将详细介绍如何利用JavaScript将这种扁平化的键名结构转换为更具可读性和操作性的嵌套数组对象。
假设我们有以下两种输入数据结构:
立即学习“Java免费学习笔记(深入)”;
1. 基础结构示例:
const inputObjectBasic = {
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"
};2. 包含嵌套数组的复杂结构示例:
const inputObjectAugmented = {
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"
};我们的目标是将这些扁平化的键名转换为对应的嵌套JavaScript对象。
对于只包含一层数组对象(如timeslots中的start和end)的结构,我们可以利用JavaScript的Object.entries、filter、map和reduce等方法进行链式处理,实现简洁高效的转换。
const inputObjectBasic = {
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"
};
const transformedObjectBasic = {
id: inputObjectBasic.id,
timeslots: Object.entries(inputObjectBasic)
.filter(([key]) => key.startsWith("timeslots")) // 1. 筛选出所有以 "timeslots" 开头的键
.map(([key, value]) => {
// 2. 使用正则表达式解析键名,提取索引和属性名
const match = key.match(/timeslots\[(\d+)\]\[(start|end)\]/);
if (match) {
const [, index, property] = match; // match[1] 是索引,match[2] 是属性名
return { [property]: value, index: parseInt(index) };
}
return null; // 如果不匹配,返回 null,后续 filter 会移除
})
.filter(item => item !== null) // 移除未能匹配的项
.reduce((acc, { index, ...rest }) => {
// 3. 聚合数据:根据索引将属性合并到对应的 timeslot 对象中
acc[index] = acc[index] || {}; // 如果该索引处还没有对象,则创建一个空对象
Object.assign(acc[index], rest); // 将解析出的属性合并到对象中
return acc;
}, []) // 初始累加器是一个空数组
};
console.log("基础转换结果:", transformedObjectBasic);
/*
输出:
{
id: "id1",
timeslots: [
{ start: "2023-06-10", end: "2023-06-09" },
{ start: "2024-06-10", end: "2024-06-09" }
]
}
*/当数据结构中包含更深层次的嵌套数组时(例如timeslots[0]disability[3]),上述reduce的链式调用可能变得复杂。此时,采用迭代方式并配合多个正则表达式匹配,可以提供更清晰的解决方案。
const inputObjectAugmented = {
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"
};
const outputObjectAugmented = { id: inputObjectAugmented.id, timeslots: [] };
const keys = Object.keys(inputObjectAugmented);
keys.forEach(key => {
// 尝试匹配 timeslots[N][start|end] 形式的键
const matchTimeSlotProp = key.match(/timeslots\[(\d+)\]\[(start|end)\]/);
if (matchTimeSlotProp) {
const index = parseInt(matchTimeSlotProp[1]); // 提取 timeslots 数组的索引
const prop = matchTimeSlotProp[2]; // 提取属性名 (start 或 end)
// 确保 timeslots 数组的该索引位置有对象
if (!outputObjectAugmented.timeslots[index]) {
outputObjectAugmented.timeslots[index] = {};
}
// 赋值属性
outputObjectAugmented.timeslots[index][prop] = inputObjectAugmented[key];
} else {
// 尝试匹配 timeslots[N]disability[M] 形式的键
const matchDisability = key.match(/timeslots\[(\d+)\]disability\[\d+\]/);
if (matchDisability) {
const index = parseInt(matchDisability[1]); // 提取 timeslots 数组的索引
const disabilityValue = inputObjectAugmented[key]; // 提取 disability 的值
// 确保 timeslots 数组的该索引位置有对象
if (!outputObjectAugmented.timeslots[index]) {
outputObjectAugmented.timeslots[index] = {};
}
// 确保 timeslots[index] 对象中有 disability 数组
if (!outputObjectAugmented.timeslots[index].disability) {
outputObjectAugmented.timeslots[index].disability = [];
}
// 将 disability 值添加到对应的数组中
outputObjectAugmented.timeslots[index].disability.push(disabilityValue);
}
}
});
console.log("进阶转换结果:", outputObjectAugmented);
/*
输出:
{
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"] }
]
}
*/以上就是JavaScript中将扁平化表单键转换为嵌套数组对象的教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号