
本文介绍如何将形如 [{manufacture, make, model}] 的扁平化数据,通过一次遍历、无嵌套循环的方式,转换为具有层级关系的嵌套结构 {manufacture, makes: [{make, models: [{model}]}]}。核心在于利用对象缓存与“获取或创建”模式提升性能与可读性。
本文介绍如何将形如 `[{manufacture, make, model}]` 的扁平化数据,通过一次遍历、无嵌套循环的方式,转换为具有层级关系的嵌套结构 `{manufacture, makes: [{make, models: [{model}]}]}`。核心在于利用对象缓存与“获取或创建”模式提升性能与可读性。
在实际开发中(尤其是处理数据库查询结果或 API 返回的扁平化列表时),常需将一维数据按多级分类聚合为树状结构。例如,汽车数据按「厂商 → 车系 → 车型」三级组织,原始数据是扁平对象数组,目标结构却要求嵌套数组形式:
[
{
"manufacture": "Ford",
"makes": [
{
"make": "Mustang",
"models": [
{ "model": "EcoBoost" },
{ "model": "GTFastback" },
{ "model": "DarkHorse" }
]
},
{
"make": "Escape",
"models": [
{ "model": "Active" },
{ "model": "Platium" }
]
}
]
}
]
直接使用 reduce + 多层 find 或嵌套 forEach 易导致 O(n³) 时间复杂度,且代码冗长难维护。更优解是采用单次遍历 + 哈希缓存策略:用一个临时对象 cache 同时管理所有层级节点的引用,避免重复查找。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
✅ 推荐实现(简洁高效版)
const flattenData = [
{ 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' }
];
// 缓存对象:键为唯一标识(如 'Ford' 或 'Ford:Mustang'),值为对应节点引用
const cache = { root: [] };
for (const { manufacture, make, model } of flattenData) {
// 获取或创建 manufacturer 级节点
const manuNode = cache[manufacture] ??= {
manufacture,
makes: []
};
if (!cache.root.includes(manuNode)) {
cache.root.push(manuNode);
}
// 获取或创建 make 级节点(用复合键避免命名冲突)
const makeKey = `${manufacture}:${make}`;
const makeNode = cache[makeKey] ??= {
make,
models: []
};
if (!manuNode.makes.includes(makeNode)) {
manuNode.makes.push(makeNode);
}
// 添加 model
makeNode.models.push({ model });
}
const nestedResult = cache.root;
console.log(JSON.stringify(nestedResult, null, 2));
? 关键设计说明
- 唯一键设计:manufacture 和 manufacture:make 作为缓存键,确保层级唯一性,避免同名厂商/车系覆盖;
- 引用复用:所有节点均为对象引用,无需深拷贝,内存友好;
- 插入去重:使用 includes() 防止同一节点被重复加入父数组(适用于数据存在顺序错乱场景);
- 时间复杂度:O(n),仅一次遍历,每项操作均为常数时间。
⚠️ 注意事项
- 若原始数据中 manufacture 或 make 字段可能为空或含特殊字符(如 :),建议预处理或改用 Symbol 或 Map 替代普通对象缓存;
- 此方案不依赖第三方库,兼容所有现代浏览器及 Node.js 环境;
- 如需支持任意深度嵌套(如增加 trim 或 year 层级),只需扩展缓存键生成逻辑与节点结构即可,模式高度可复用。
该方法兼顾性能、可读性与扩展性,是处理多级分组映射问题的工业级实践方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










