如何为嵌套JSON数组对象添加id、parent和droppable属性?
问题分析与解决
问题场景
现有嵌套JSON结构:
[ { "heading": [ { "name": "Heading 01", "Items": [ { "name": "Item 01", "layers": [ { "name": "layer01", }, { "name": "layer02", } ] } ] } ] } ]
需要为每个层级对象添加id(自增唯一值)、parent(父节点ID)、droppable(区分是否可拖拽),期望输出结构如下:
[{ "id": 1, "parent": 0, "droppable":true, "heading": [ { "name": "Heading 01", "id": 2, "parent": 1, "droppable":true, "Items": [ { "name": "Item 01", "id": 3, "parent": 2, "droppable":true, "layers": [ { "name": "layer01", "parent": 3, "id":4, "droppable":false }, { "name": "layer02", "parent": 3, "id":5, "droppable":false } ] } ] } ] }]
(注:原期望中两个layer的ID重复为4,这里调整为唯一ID,符合常规ID设计逻辑)
原代码问题
你当前的递归函数存在以下问题:
- ID生成逻辑错误:用数组索引作为ID,会导致不同层级ID重复,且没有实现自增唯一值
- 未处理所有嵌套数组:只处理了
heading,完全没处理Items,layers也被注释掉 - 缺少
droppable字段:没有根据层级设置对应的布尔值 - 冗余代码:
JSON.parse(${i})完全没必要,直接用数字即可
修正后的代码
let treedata = [ { "heading": [ { "name": "Heading 01", "Items": [ { "name": "Item 01", "layers": [ { "name": "layer01", }, { "name": "layer02", } ] } ] } ] } ]; function addUniqueID(arr, parentId, idCounter) { arr.forEach(obj => { // 分配自增唯一ID obj.id = idCounter.current++; // 设置父节点ID obj.parent = parentId; // 根据当前节点类型设置droppable if (obj.heading) { obj.droppable = true; addUniqueID(obj.heading, obj.id, idCounter); } else if (obj.Items) { obj.droppable = true; addUniqueID(obj.Items, obj.id, idCounter); } else if (obj.layers) { obj.droppable = true; addUniqueID(obj.layers, obj.id, idCounter); } else { // 最底层的layer节点不可拖拽 obj.droppable = false; } }); } // 初始化ID计数器,从1开始 const idCounter = { current: 1 }; // 顶层节点的父ID为0 addUniqueID(treedata, 0, idCounter); console.log(JSON.stringify(treedata, null, 2));
代码说明
- 自增ID维护:用
idCounter对象(引用类型)在递归中持续更新ID,确保全局唯一 - 父ID传递:递归时传入当前节点的ID作为子节点的父ID,层级关系准确
- 层级判断:根据节点包含的字段(heading/Items/layers)区分层级,设置对应的
droppable值 - 全覆盖遍历:处理所有嵌套数组,确保每个节点都被添加目标字段
内容的提问来源于stack exchange,提问作者Sacrlett_jose
相关产品推荐
相关产品推荐

