js 通过id、pid遍历集合获得树结构
原数据
let adreeJson = [ {id: 1, name: '陕西省', pid: 0}, {id: 2, name: '山西省', pid: 0}, {id: 3, name: '广东省', pid: 0}, {id: 4, name: '西安市', pid: 1}, {id: 5, name: '宝鸡市', pid: 1}, {id: 6, name: '莲湖区', pid: 4}, {id: 7, name: '雁塔区', pid: 4}, {id: 8, name: '深圳市', pid: 3}, {id: 9, name: '宝安区', pid: 8}, ]
需解析成:
let adressTree = [ { id: 1, name: '陕西省', pid: 0, child: [ { id: 4, name: '西安市', pid: 1, child: [ {id: 6, name: '莲湖区', pid: 4}, {id: 7, name: '雁塔区', pid: 4}, ] }, { id: 5, name: '宝鸡市', pid: 1 }, ] }, { id: 2, name: '山西省', pid: 0, child: [] }, { id: 3, name: '广东省', pid: 0, child: [ { id: 8, name: '深圳市', pid: 3, child: [ {id: 9, name: '宝安区', pid: 8} ] } ] }, ]
方法一:
先获取顶级节点,然后再通过递归获取其子节点
function getTop(arry) { return arry.filter(item => item.id == item.pid || item.pid == 0) } function getChild(pArry, arry) { pArry.forEach(idt => { idt.child = arry.filter(item => idt.id == item.pid) if ((idt.child).length > 0) { getChild(idt.child, arry) } }) return pArry } let topTree = getTop(adreeJson) console.log(getChild(topTree, adreeJson))
方法二:
也是先获取父节点,然后再递归得到子节点
//获取顶级节点 function getParent(arry, id) { var newArry = new Array(); for (let i in arry) { if (arry[i].pid == id) newArry.push(arry[i]); } return newArry; } function getTree(arrys, id) { //深拷贝,否则会影响原数组 let arry = JSON.parse(JSON.stringify(arrys)) let childArry = getParent(arry, id); if (childArry.length > 0) { for (let i in childArry) { //递归得到每个父节点的子节点 let _c_c_a = getTree(arry, childArry[i].id); _c_c_a.length > 0 ? childArry[i].child = _c_c_a : childArry[i].child = [] } } return childArry } console.log(getTree(adreeJson, 0))
方法三:
/*通过定义map,key为当前对象id,value为该对象 遍历集合,得到对象顶级节点放到集合中返回 不是顶级的就是当前对象得子节点,将对象放到该节点下*/ function toTree(nodes) { let result = [] //如果值是 Array,则为true; 否则为false。 if (!Array.isArray(nodes)) { return result } //深拷贝,否则会影响原数组 let node = JSON.parse(JSON.stringify(nodes)) //根据父节点进行拼接子节点, node.forEach(item => delete item.child)//已经有的话就删掉 //把每一项的引用放入map对象里 let map = {} node.forEach(item => map[item.id] = item) let newNode = [] node.forEach(dt => { let parents = map[dt.pid] if (parents) { //如果 map[dt.pid] 有值 则 parents 为 dt 的父级 //判断 parents 里有无child 如果没有则创建 如果有则直接把 dt push到child里 ((parents.child) || (parents.child = [])).push(dt) //等同于: // if (!parents.child) { // parents.child = [] // } // (parents.child).push(dt) } else { newNode.push(dt) } }) return newNode } console.log(toTree(adreeJson))
方法四:
var flatToTree = flats => { flats.forEach(item => { var index = flats.findIndex(item1 => item1.id === item.pid) if (index !== -1) { //判断 flats[index] 里有无child 如果没有则创建 如果有则直接把 item push到child里 ((flats[index].child) || (flats[index].child = [])).push(item) //等同于: // if (!flats[index].child) { // flats[index].child = [] // } // flats[index].child.push(item) //或: // flats[index].child = flats[index].child || [] // flats[index].child.push(item) } }) return flats.filter(dt => dt.pid === 0)//只获取父节点为0的值 } console.log(flatToTree(adreeJson))