【比较难】JS多层递归遍历

小弟初学js,遇到一个难题,关于把一个多层数据结构的转换成treeview可识别的格式问题

原数据格式为:

{
  "root": "body",
  "structure": {
    "body": [
        "head",
        "foot"
    ],
    "head": [
      "control",
      "tabs"
    ],
    "control": [
      "c123",
      "c456",
      "c789"
    ],
    "tabs": [
      "33",
      "44"
    ],
    "foot": [
      "footLeft",
      "divEnd"
    ],
    "footLeft": [
      "footLeftContainer"
    ],
    "footLeftContainer": [
      "add22",
      "ffff",
      "fff"
    ],
    "divEnd": [
      "divEnd$111"
    ]
  }
};

期望处理成的格式为:


    [
  {
    text: "body",
    nodes: [
      {
        text: "head",
        nodes: [
          {
            text: "control",
            nodes: [
              {
                text: "c123"
              },
              {
                text: "c456"
              },
              {
                text: "c789"
              }
            ]
          },
          {
            text: "tabs",
            nodes: [
              {
                text: "t33"
              },
              {
                text: "t44"
              }
            ]
          }
        ]
      },
      {
        text: "foot",
        nodes: [
          {
            text: "footLeft",
            nodes: [
              {
                text: "footLeftContainer",
                nodes: [
                  {
                    text: "add22"
                  },
                  {
                    text: "ffff"
                  },
                  {
                    text: "fff"
                  }
                ]
              }
            ]
          },
          {
            text: "divEnd",
            nodes: [
              {
                text: "divEnd$111"
              }
            ]
          }
        ]
      }
    ]
  }
]

原理就是从structure中层层找child,起始点是root节点的值(即"body")
每个节点的child如果不在structure一级节点中,则认为是叶子节点
想了一天,没有好办法,来求助各位前辈

阅读 3.3k
2 个回答
// 等待转换的对象
list = {
  "root": "body",
  "structure": {
    "body": [
        "head",
        "foot"
    ],
    "head": [
      "control",
      "tabs"
    ],
    "control": [
      "c123",
      "c456",
      "c789"
    ],
    "tabs": [
      "33",
      "44"
    ],
    "foot": [
      "footLeft",
      "divEnd"
    ],
    "footLeft": [
      "footLeftContainer"
    ],
    "footLeftContainer": [
      "add22",
      "ffff",
      "fff"
    ],
    "divEnd": [
      "divEnd$111"
    ]
  }
};

function toA(list,parent,key){
    // 创建一个当前节点
    const current = {
        text:key
    }
    // 给父节点添加nodes 数组
    !parent.nodes && (parent.nodes = []);
    // 同时将当前的节点添加到父亲节点
    parent.nodes.push(current);
    // 遍历子节点
    list[key] && list[key].forEach(item=>{
        toA(list,current,item);
    });

}
// 用于保存节点
const listOk = {
    
};
// list.structure 等待转换的对象 listOk 转换后的对象 body 初始化key
toA(list.structure,listOk,'body');
// 打印结果
console.log(JSON.stringify(listOk.nodes,null,2))

    const data = {
        root: 'body',
        structure: {
          body: ['head', 'foot'],
          head: ['control', 'tabs'],
          control: ['c123', 'c456', 'c789'],
          tabs: ['33', '44'],
          foot: ['footLeft', 'divEnd'],
          footLeft: ['footLeftContainer'],
          footLeftContainer: ['add22', 'ffff', 'fff'],
          divEnd: ['divEnd$111'],
        },
      };

      /**
       * @param {typeof data} data
       */

      function conver(data) {
        const ret = [];

        const coll = data.structure;
        const root = { text: data.root };
        const map = { [data.root]: root };

        Object.keys(coll).forEach(key => {
          map[key] = map[key] || { text: key };

          coll[key].forEach(item => {
            map[item] = map[item] || { text: item };
          });
        });

        Object.keys(coll).forEach(key => {
          coll[key].forEach(item => {
            if (map[key]) {
              map[key].nodes = map[key].nodes || [];
              map[key].nodes.push(map[item]);
            }
          });
        });

        console.log(root);
      }

      conver(data);

先遍历每个节点存在 hash 表里, 然后再遍历, 根据 parent 关系找到父节点.

像楼上一样, data.structure 这个也可以理解为一张图, key 是一个顶点, 数组是它的邻边集合. 非递归也可以的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题