![如何将带索引的字段名(如 field[0])自动聚合成数组值](https://img.php.cn/upload/article/001/246/273/179352421354202.jpg?x-oss-process=image/resize,p_40)
本文介绍如何在 JavaScript 中将具有相同基础名称但带方括号索引(如 "created_at[0]"、"created_at[1]")的对象,按基础名分组并合并为单个对象,其 value 字段自动转为数组,而普通字段保持原值。
本文介绍如何在 javascript 中将具有相同基础名称但带方括号索引(如 `"created_at[0]"`、`"created_at[1]"`)的对象,按基础名分组并合并为单个对象,其 `value` 字段自动转为数组,而普通字段保持原值。
在表单处理、API 请求参数聚合或动态筛选条件(如日期范围 start_time[0]/start_time[1])等场景中,常会遇到字段名携带索引(如 name="email" 和 name="created_at[0]")的情况。后端可能期望将同名索引字段合并为数组,而前端需将原始扁平数据结构转换为语义清晰的嵌套结构。
核心思路是:提取字段的基础名称(如 "created_at[0]" → "created_at"),按该名称分组,并根据是否含 [ 判断是否应归入数组。
以下是一个健壮、高效且可读性强的实现:
const transformIndexedFields = (items) => {
return Object.values(
items.reduce((acc, { name, value, type, column }) => {
// 提取基础名称:截取 '[' 前的部分;若无 '[',则保留原名
const bracketIndex = name.indexOf('[');
const baseName = bracketIndex === -1 ? name : name.substring(0, bracketIndex);
const isIndexed = bracketIndex !== -1;
// 若该 baseName 尚未初始化,则创建新条目
if (!acc[baseName]) {
acc[baseName] = {
column: baseName,
name: baseName,
type: isIndexed ? 'range' : (type || 'like'),
value: isIndexed ? [] : value
};
}
// 若为索引字段,推入数组;否则保持原子值(注意:首次出现非索引字段时已赋值,后续同名索引字段不覆盖)
if (isIndexed) {
acc[baseName].value.push(value);
}
return acc;
}, {})
);
};
// 示例输入
const input = [
{
"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>"
}
];
console.log(transformIndexedFields(input));
// 输出:
// [
// {
// "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],避免字符串分割开销,性能更优; - 显式判断
isIndexed,确保逻辑清晰,避免误判(如字段名含[但非索引格式); - 利用
Object.values()统一输出为数组,符合常见数据消费习惯; -
type字段优先使用原始type(如"like"),对索引字段默认设为"range",也可按需扩展为从首个匹配项继承; -
不依赖 Nullish Coalescing Assignment (
??=),兼容性更好(支持 IE11+ 及所有现代浏览器)。
⚠️ 注意事项:
- 若同一基础名下混用索引与非索引字段(如
"user[0]"和"user"),当前逻辑以首次出现类型为准——建议数据源保持语义一致; - HTML 转义字符(如邮箱中的
&)无需额外处理,因value原样保留; - 如需支持多维索引(如
"data[0][1]"),需升级解析逻辑(例如正则匹配^([^\[]+)\[)。
此方案简洁、可维护、零依赖,适用于表单序列化、搜索条件组装、配置项标准化等典型工程场景。










