
本文介绍如何将一组按字段分散存储的对象数组(如 company、block、start_date、end_date 各占一个对象),依据字段语义规律,高效合并为多个完整业务对象,适用于日程、预约、资源分配等场景。
本文介绍如何将一组按字段分散存储的对象数组(如 company、block、start_date、end_date 各占一个对象),依据字段语义规律,高效合并为多个完整业务对象,适用于日程、预约、资源分配等场景。
在实际开发中,我们常遇到后端返回的扁平化、非结构化数据:同一业务实体(如一条日程记录)的多个字段被拆分成独立对象,依次排列在数组中。例如,company、block、start_date、end_date 各自占据一个对象,且每组四字段循环出现。目标是将它们按顺序“聚合成”结构清晰的完整对象。
核心思路是:识别每组数据的起始标识字段(如 “company”),以此作为新对象的创建信号;后续同组字段则累加到当前对象中。
以下是一个健壮、可读性强的实现方案:
function groupByFirstKey(arr) { if (!Array.isArray(arr) || arr.Length === 0) return []; // 取第一个对象的首个键名(假设每组均以该键开头) const [startKey] = Object.keys(arr[0]); const result = []; let currentObj = null; for (const item of arr) { const entries = Object.entries(item); if (entries.length === 0) continue; // 跳过空对象 const [key, value] = entries[0]; // 假设每个对象仅含一个键值对 if (key === startKey) { // 遇到新组起点,创建新对象并推入结果 currentObj = { [key]: value }; result.push(currentObj); } else if (currentObj !== null) { // 累加到当前对象(确保不覆盖已有同名字段) currentObj[key] = value; } } return result; } // 示例数据 const input = [ { "company": "test" }, { "block": "test" }, { "start_date": "15/08/2023 15:00" }, { "end_date": "15/08/2023 15:00" }, { "company": "test1" }, { "block": "test1" }, { "start_date": "15/08/2023 15:00" }, { "end_date": "15/08/2023 15:00" } ]; console.log(groupByFirstKey(input)); // 输出: // [ // { company: "test", block: "test", start_date: "15/08/2023 15:00", end_date: "15/08/2023 15:00" }, // { company: "test1", block: "test1", start_date: "15/08/2023 15:00", end_date: "15/08/2023 15:00" } // ]
✅ 关键优势说明:
- 无需硬编码字段名:自动提取首个对象的首键(如 “company”)作为分组锚点,提升通用性;
- 健壮容错:跳过空对象,避免 Object.entries() 报错;
- 语义清晰:变量命名(startKey, currentObj)直指逻辑意图,便于团队维护;
- 可扩展性强:若后续字段增加(如 “location”),只要保持相同分组顺序,代码无需修改。
⚠️ 注意事项:
- 本方案依赖字段顺序与分组规律(即每组以 startKey 开头,其余字段严格按序跟随)。若数据无序或存在缺失字段,需先校验或预处理;
- 若存在多层级嵌套或动态字段组合,建议改用更声明式的方案(如 reduce + 状态机),或前置 Schema 定义;
- 生产环境建议添加类型检查(如使用 TypeScript)或输入校验(如 arr.every(item => typeof item === ‘object’ && Object.keys(item).length === 1))。
总结而言,该方法以最小认知成本实现了结构重组,在保证简洁性的同时兼顾可读性与鲁棒性,是处理此类「扁平化业务数据聚合」问题的推荐实践。