You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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));

代码说明

  1. 修正初始节点:之前你写的resData.x是错误的,需要从resData.style对象中获取坐标和尺寸,这是输入JSON的结构决定的。
  2. 递归函数processNode:
    • 首先根据当前节点的op_success和op_failure状态,生成对应的输出连接器列表。
    • 创建符合输出格式要求的节点对象,并添加到nodes数组。
    • 如果当前节点有父节点,生成对应的连接关系并添加到connections数组,确保源节点、源连接器索引、目标节点、目标连接器索引都正确。
    • 分别递归处理op_success和op_failure指向的下一级节点,传递当前节点ID和对应的输出连接器索引,保证连接关系的准确性。
  3. 启动递归:从flow节点的op_start指向的第一个节点开始,触发整个递归遍历流程。

这样就能自动遍历所有关联节点,生成完整的nodes和connections结构啦!

内容的提问来源于stack exchange,提问作者Arpit Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:30:50