![如何将带索引的字段名(如 field[0])自动归并为数组值](https://img.php.cn/upload/article/001/246/273/179352283281081.jpg?x-oss-process=image/resize,p_40)
本文介绍如何在 JavaScript 中识别形如 name[0]、name[1] 的字段名,将其同名基底(如 name)归为一组,并将对应 value 合并为数组;普通字段则保持原值不变,最终输出结构清晰的规范化数据。
本文介绍如何在 javascript 中识别形如 `name[0]`、`name[1]` 的字段名,将其同名基底(如 `name`)归为一组,并将对应 `value` 合并为数组;普通字段则保持原值不变,最终输出结构清晰的规范化数据。
在表单处理、动态筛选条件(如时间范围 created_at[0]/created_at[1])或后端 API 适配等场景中,常会遇到字段名携带方括号索引(如 "email", "created_at[0]", "created_at[1]")的情况。目标是将所有 xxx[n] 归类到统一键 xxx 下,并将它们的 value 组织为数组,而独立字段(无 [)则保留原始值。
核心思路是:按字段基名分组 + 动态初始化 + 类型感知赋值。以下为推荐实现(兼顾可读性与性能):
const transformIndexedFields = (inputArray) => {
return Object.values(
inputArray.reduce((acc, { name, value, type }) => {
// 提取基名(如 "created_at[0]" → "created_at")
const bracketIndex = name.indexOf('[');
const baseName = bracketIndex === -1 ? name : name.slice(0, bracketIndex);
const isIndexed = bracketIndex !== -1;
// 若该基名尚未存在,初始化对象
if (!acc[baseName]) {
acc[baseName] = {
column: baseName,
name: baseName,
type: isIndexed ? 'range' : type || 'like',
value: isIndexed ? [] : value
};
}
// 若为索引字段,追加到 value 数组;否则已直接赋值
if (isIndexed) {
acc[baseName].value.push(value);
}
return acc;
}, {})
);
};
// 使用示例
const rawData = [
{
"column": "created_at[0]",
"name": "created_at[0]",
"type": "range",
"value": "2022-12-26 00:00:00"
},
{
"column": "created_at[1]",
"name": "created_at[1]",
"type": "range",
"value": "2023-12-26 23:59:59"
},
{
"column": "email",
"name": "email",
"type": "like",
"value": "<a class='\"__cf_email__\"' data-cfemail='\"61000021060c00080d4f020e0c\"' href="%5C%22/cdn-cgi/l/email-protection%5C%22">[email protected]</a>"
}
];
const result = transformIndexedFields(rawData);
console.log(result);
// 输出:
// [
// {
// "column": "created_at",
// "name": "created_at",
// "type": "range",
// "value": ["2022-12-26 00:00:00", "2023-12-26 23:59:59"]
// },
// {
// "column": "email",
// "name": "email",
// "type": "like",
// "value": "<a ...>[email protected]</a>"
// }
// ]
✅ 关键设计说明:
- 使用
indexOf('[')替代split('[')[0],避免字符串分割开销,提升性能; - 利用
if (!acc[baseName]) {...}显式初始化,语义清晰且兼容旧版 JS(无需??=); -
type字段根据是否索引智能推导:索引字段默认设为'range'(符合示例逻辑),非索引字段复用原始type; - 最终通过
Object.values()转为数组,确保输出为规范的扁平列表。
⚠️ 注意事项:
- 输入数据中相同基名的索引字段应具有相同
type(如均为"range"),否则后续逻辑可能需扩展校验; - 若存在嵌套索引(如
"items[0][name]"),当前逻辑仅提取首层基名("items"),如需深度解析需改用正则(如/^([^[]+)/); - HTML 字符串中的
、>或邮箱混淆代码(如data-cfemail)属于业务数据,本方案不做清洗,保持原样透传。
该方案简洁、健壮、易于维护,可直接集成至表单序列化、API 请求预处理等流程中。










