Angular 2/4中如何将指定格式数组转换为树形结构?
把扁平位置数组转成树形结构的实现方案
嘿,我来帮你搞定这个扁平数组转树形结构的需求!这种层级数据转换在项目里超常见,我给你写个简洁高效的JavaScript实现,逻辑一目了然。
先看目标树形结构
最终我们要得到的结构大概是这样:
[ { "pk_location_id": 1, "locationname": "Oman", "parent_location_id": 0, "has_children": true, "children": [ { "pk_location_id": 2, "locationname": "Muscat", "parent_location_id": 1, "has_children": true, "children": [ { "pk_location_id": 4, "locationname": "Ruwi", "parent_location_id": 2, "has_children": false, "children": [] } ] }, { "pk_location_id": 3, "locationname": "Seeb", "parent_location_id": 1, "has_children": false, "children": [] } ] } ]
实现代码
咱用两步走的方式,效率拉满:
function buildLocationTree(flatArray) { // 第一步:创建节点映射表,快速查找父节点 const nodeMap = {}; const tree = []; // 先把所有节点存入映射表,同时初始化children数组 flatArray.forEach(node => { nodeMap[node.pk_location_id] = { ...node, children: [] }; }); // 第二步:遍历每个节点,挂载到对应的父节点下 flatArray.forEach(node => { const currentNode = nodeMap[node.pk_location_id]; if (node.parent_location_id === 0) { // parent为0的是根节点,直接加入树 tree.push(currentNode); } else { // 找到父节点,把当前节点加到父节点的children里 const parentNode = nodeMap[node.parent_location_id]; if (parentNode) { parentNode.children.push(currentNode); } } }); return tree; } // 测试你的数组 const flatLocations = [ {"pk_location_id":1,"locationname":"Oman","parent_location_id":0,"has_children":true}, {"pk_location_id":2,"locationname":"Muscat","parent_location_id":1,"has_children":true}, {"pk_location_id":3,"locationname":"Seeb","parent_location_id":1,"has_children":false}, {"pk_location_id":4,"locationname":"Ruwi","parent_location_id":2,"has_children":false} ]; const locationTree = buildLocationTree(flatLocations); console.log(JSON.stringify(locationTree, null, 2));
代码逻辑说明
- 节点映射表:用对象存储每个节点的id和节点本身,这样查找父节点的时间复杂度是O(1),比遍历数组找父节点的O(n²)高效太多,数据量大的时候优势特别明显。
- 初始化children:给每个节点都加上
children空数组,避免后续操作时出现未定义的错误。 - 挂载节点:遍历每个节点,判断是根节点(parent_location_id=0)就直接加入树,否则找到父节点并挂载到它的children数组里。
这个方案兼容性好,不管是浏览器端还是Node.js环境都能直接用,而且逻辑清晰,后续维护也方便~
内容的提问来源于stack exchange,提问作者Amruta Wandakar
相关产品推荐
相关产品推荐

