树结构到平面数组 Javascript

时间:2021-07-15 02:02:34

标签: javascript arrays tree

Flat array to tree Javascript 的问题进行跟进

正在寻找如何将树结构展平为可用于插入 sql db 的数组的解决方案。

我发现其他一些解决方案使用递归,但我希望找到有关递归解决方案如何工作的解释。

const tree = [
  {
    1: {
      label: 'root',
      children: [
        {
          2: {
            label: 'ant',
            children: [],
          },
        },
        {
          3: {
            label: 'bear',
            children: [
              {
                4: {
                  label: 'cat',
                  children: [],
                },
              },
              {
                5: {
                  label: 'dog',
                  children: [
                    {
                      6: {
                        label: 'elephant',
                        children: [],
                      },
                    },
                  ],
                },
              },
            ],
          },
        },
        {
          7: {
            label: 'frog',
            children: [],
          },
        },
      ],
    },
  },
];

const expectedFlattenedTree = [
  { id: 1, label: 'root', parent_id: null },
  { id: 2, label: 'ant', parent_id: 1 },
  { id: 3, label: 'bear', parent_id: 1 },
  { id: 4, label: 'cat', parent_id: 3 },
  { id: 5, label: 'dog', parent_id: 3 },
  { id: 6, label: 'elephant', parent_id: 5 },
  { id: 7, label: 'frog', parent_id: 1 },
];

2 个答案:

答案 0 :(得分:1)

这是一个简单的递归函数

const tree = 
  [ { 1: { label: 'root', children: 
        [ { 2: { label: 'ant', children: [] } } 
        , { 3: { label: 'bear', children: 
              [ { 4: { label: 'cat', children: [] } } 
              , { 5: { label: 'dog', children: 
                    [ { 6: { label: 'elephant', children: [] } } 
                    ] 
          } } ] } } 
        , { 7: { label: 'frog', children: [ ] } } 
  ] } } ] 

const flatTree = []

function treeRun (xTree,parent_id)
  {
  xTree.forEach(el => 
    {
    let [k,v] = Object.entries(el)[0]
    flatTree.push({id:k, label:v.label, parent_id })
    if (v.children.length > 0)
      treeRun (v.children,k)
    })  
  }
treeRun (tree,null)

console.log( flatTree )
.as-console-wrapper {max-height: 100%!important;top:0 }

答案 1 :(得分:0)

如果用浏览器一步一步调试脚本,会更直观地理解递归。
在这里,我简要介绍一下递归。

  • 我们将在顶层调用平面函数和循环
  • 构造当前的obj或节点后,这仍然是正常的操作
  • 我们在flat with children节点中调用flat,然后进入sub level,此时就像空间跳跃魔术。我们进入另一个带有children的flat函数,但是当前flat函数还没有完成。
  • 子级平面(或子级的子级)完成后,顶层平面继续运行,并连接创建的列表

const tree=[{1:{label:"root",children:[{2:{label:"ant",children:[]}},{3:{label:"bear",children:[{4:{label:"cat",children:[]}},{5:{label:"dog",children:[{6:{label:"elephant",children:[]}}]}}]}},{7:{label:"frog",children:[]}}]}}];

function flat(items,parent_id){
  var flated = []
  for (var item of items){
    for (var id in item){
      const obj = item[id]
      //construct flat item and append to list
      flated.push({"id":id,"label":obj['label'],"parent_id":parent_id})
      
      if (obj['children'].length==0){
        continue
      }
      //use children list go into sub function
      const sub_flated = flat(obj['children'],id)
      
      //concat array list using ES6
      flated = [...flated,...sub_flated]
    }
  }
  return flated
}
console.log(flat(tree,null))