
本文介绍如何使用缓存对象与“获取或创建”模式,将含重复层级字段(如 manufacture、make、model)的扁平数组,一次性转换为符合 {manufacture, makes: [{make, models: [{model}]}]} 规范的嵌套 JSON 结构,代码简洁、性能优异且易于扩展。
本文介绍如何使用缓存对象与“获取或创建”模式,将含重复层级字段(如 manufacture、make、model)的扁平数组,一次性转换为符合 `{manufacture, makes: [{make, models: [{model}]}]}` 规范的嵌套 json 结构,代码简洁、性能优异且易于扩展。
在实际前端开发或数据聚合场景中,后端常返回高度扁平化的表格型数据(如数据库查询结果),但前端 UI 或 API 请求往往需要结构化的嵌套格式(例如树形菜单、分组列表)。手动遍历 + 多重条件判断虽可行,却易出错、难维护。更优解是利用 JavaScript 对象的键唯一性与引用特性,构建多级缓存映射,实现一次遍历、动态归并。
以下是一个生产就绪的实现方案:
const data = [
{ manufacture: 'Ford', make: 'Mustang', model: 'EcoBoost' },
{ manufacture: 'Ford', make: 'Mustang', model: 'GTFastback' },
{ manufacture: 'Ford', make: 'Mustang', model: 'DarkHorse' },
{ manufacture: 'Ford', make: 'Escape', model: 'Active' },
{ manufacture: 'Ford', make: 'Escape', model: 'Platium' },
{ manufacture: 'Toyota', make: 'Camry', model: 'XSE' },
{ manufacture: 'Toyota', make: 'Camry', model: 'TRD' },
{ manufacture: 'Toyota', make: 'Camry', model: 'XLE' },
{ manufacture: 'Toyota', make: 'Supra', model: '2.0' },
{ manufacture: 'Toyota', make: 'Supra', model: '3.0' }
];
// 核心:单对象缓存 + 根数组
const cache = { _: [] };
// 工具函数:安全添加并返回被添加项(支持链式赋值)
const append = (arr, item) => (arr.push(item), item);
for (const { manufacture, make, model } of data) {
// 一级:按 manufacture 分组 → 若不存在则创建并加入根数组
const manuGroup = cache[manufacture] ??= append(cache._, { manufacture, makes: [] });
// 二级:按 manufacture+make 复合键分组 → 避免 make 名跨厂商冲突(如 Ford/Camry vs Toyota/Camry)
const makeGroup = cache[`${manufacture}:${make}`] ??= append(manuGroup.makes, { make, models: [] });
// 三级:直接推入 model 对象
makeGroup.models.push({ model });
}
// 最终结果即为 cache._
console.log(cache._);
输出结构示例:
[
{
"manufacture": "Ford",
"makes": [
{
"make": "Mustang",
"models": [
{"model": "EcoBoost"},
{"model": "GTFastback"},
{"model": "DarkHorse"}
]
},
{
"make": "Escape",
"models": [
{"model": "Active"},
{"model": "Platium"}
]
}
]
},
{
"manufacture": "Toyota",
"makes": [
/* ... */
]
}
]
✅ 关键设计亮点:
- 零重复遍历:仅需 O(n) 时间复杂度,远优于嵌套 find() 的 O(n²) 方案;
- 键名防冲突:用 manufacture:make 作为二级键,确保不同厂商下同名 make(如 “Camry”)互不干扰;
- 内存友好:所有嵌套对象均通过引用复用,无深拷贝开销;
- 可扩展性强:如需增加 trim 层级,只需新增一级缓存键(如 ${manufacture}:${make}:${trim})和对应数组字段即可。
⚠️ 注意事项:
- 确保原始数据字段名准确(如 manufacture 而非 manufacturer),建议配合 TypeScript 接口或运行时校验;
- 若数据量极大(>10 万条),可考虑流式处理或 Web Worker 卸载主线程;
- 该方案默认保留原始数据顺序(因 push 顺序与输入一致),如需按字母排序,可在最终结果上对 makes 和 models 数组调用 sort()。
此方法兼顾简洁性、性能与可维护性,是处理层级聚合类数据转换的经典范式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











