输出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];});