乐趣区

关于javascript:扁平数组转树形结构的几种实现

输出 source:

[
    {
        id: 1,
        pid: 0,
        name: 'body'
    }, {
        id: 2,
        pid: 1,
        name: 'title'
    }, {
        id: 3,
        pid: 2,
        name: 'div'
    },
    {
        id: 4,
        pid: 0,
        name: 'div'
    },
    {
        id: 9,
        pid: 4,
        name: 'div'
    }
]

输入:

[
    {
        id: 1,
        pid: 0,
        children: [
          {
             id: 2,
             pid: 1,
             children: [
                {
                  id: 3,
                  pid: 2,

                }
             ]
          }
        ]
    },{
        id: 4,
        pid: 0,
        children: [
         {
           id: 9,
           pid: 4
         }
        ]

    }
]

实现 1:

function  fn(data) {let map = {};
    let result = [];
    // 存映射,不便取值
    data.forEach((el) => {map[el.id] = el;
    });
    data.forEach((item) => {const father = map[item.pid];
        if (father) {(father.children || (father.children = [])).push(item);
        } else {result.push(item);
        }
    });

    return result;
}
fn(source)

实现 2:

function lookupChildren (target) {let source = JSON.parse(JSON.stringify(target))
    let newAry = []
    let i = 0
    while (i < source.length) {let _pitem = source[i]
        // 找以后项所有子节点
        let _ch = source.filter(item => item.pid === _pitem.id)
        let _father = source.find(item => _pitem.pid === item.id)
        _pitem.children = _ch
        !_father && newAry.push(_pitem)
        i++
    }
    return newAry
}
lookupChildren(source)

实现 3:

// 找出根节点
let root = source.filter(({pid}) => !source.find((item) => (item.id === pid)))
const getChilds = (list) => {
    return list.map(item => {let children = source.filter((temp) => temp.id === item.pid)
        item.children = getChilds(children)
        return item
    })
}
getChilds(root)

实现 4:

const idMapping = source.reduce((acc, el, i) => {acc[el.id] = i;
  return acc;
}, {});
let root;
source.forEach(el => {
  // 判断根节点
  if (el.parentId === null) {
    root = el;
    return;
  }
  // 用映射表找到父元素
  const parentEl = data[idMapping[el.pid]];
  // 把以后元素增加到父元素的 `children` 数组中
  parentEl.children = [...(parentEl.children || []), el];
});
退出移动版