如何用JavaScript递归函数实现指定JSON结构转换?
解决方案:递归生成节点与连接关系
我来帮你搞定这个递归遍历节点和生成连接关系的问题!你的基础代码已经搭好了,只需要补充递归逻辑来处理所有后续节点,同时维护好连接关系就行。
完整代码实现
var resData = response.data; // 输入JSON数据 // 初始化结果结构,修正第一个节点的style属性取值 var newDefinition = { "nodes": [ { "name": resData.name, "id": resData.id, "x": resData.style.x, "y": resData.style.y, "width": resData.style.width, "inputConnectors": [], "outputConnectors": [ { "name": "op_start" } ] } ], "connections": [] }; // 递归处理节点及其关联的子节点 function processNode(currentNode, nodeType, parentNodeId, parentOutputIndex) { // 生成当前节点的输出连接器列表(根据op_success和op_failure是否存在) const outputConnectors = []; if (currentNode.op_success !== null) { outputConnectors.push({ name: "op_success" }); } if (currentNode.op_failure !== null) { outputConnectors.push({ name: "op_failure" }); } // 创建当前节点的结构 const node = { "name": nodeType, // 节点名称使用模块类型(如web_hook、ring) "id": currentNode.id, "x": currentNode.style.x, "y": currentNode.style.y, "width": currentNode.style.width, "inputConnectors": [ { "name": "iA" } ], // 子节点默认一个输入连接器 "outputConnectors": outputConnectors }; // 将节点添加到nodes数组 newDefinition.nodes.push(node); // 如果有父节点,添加连接关系 if (parentNodeId !== undefined) { newDefinition.connections.push({ "source": { "nodeID": parentNodeId, "connectorIndex": parentOutputIndex }, "dest": { "nodeID": currentNode.id, "connectorIndex": 0 // 输入连接器只有一个,固定索引0 } }); } // 递归处理op_success指向的节点 if (currentNode.op_success !== null && currentNode.op_success_type) { const nextType = currentNode.op_success_type; const nextId = currentNode.op_success; const nextNode = resData.modules[nextType][nextId]; // op_success对应输出连接器的索引0(因为我们先添加的op_success) processNode(nextNode, nextType, currentNode.id, 0); } // 递归处理op_failure指向的节点 if (currentNode.op_failure !== null && currentNode.op_failure_type) { const nextType = currentNode.op_failure_type; const nextId = currentNode.op_failure; const nextNode = resData.modules[nextType][nextId]; // op_failure的索引:如果有op_success则是1,否则是0 const outputIndex = currentNode.op_success !== null ? 1 : 0; processNode(nextNode, nextType, currentNode.id, outputIndex); } } // 启动递归:处理flow节点连接的第一个子节点 const firstNextType = resData.op_start_type; const firstNextId = resData.op_start; const firstNextNode = resData.modules[firstNextType][firstNextId]; processNode(firstNextNode, firstNextType, resData.id, 0); // 现在newDefinition就是你需要的输出结构 console.log(JSON.stringify(newDefinition, null, 2));
代码说明
- 修正初始节点:之前你写的
resData.x是错误的,需要从resData.style对象中获取坐标和尺寸,这是输入JSON的结构决定的。 - 递归函数
processNode:- 首先根据当前节点的
op_success和op_failure状态,生成对应的输出连接器列表。 - 创建符合输出格式要求的节点对象,并添加到
nodes数组。 - 如果当前节点有父节点,生成对应的连接关系并添加到
connections数组,确保源节点、源连接器索引、目标节点、目标连接器索引都正确。 - 分别递归处理
op_success和op_failure指向的下一级节点,传递当前节点ID和对应的输出连接器索引,保证连接关系的准确性。
- 首先根据当前节点的
- 启动递归:从flow节点的
op_start指向的第一个节点开始,触发整个递归遍历流程。
这样就能自动遍历所有关联节点,生成完整的nodes和connections结构啦!
内容的提问来源于stack exchange,提问作者Arpit Kumar
相关产品推荐
相关产品推荐

