把平铺的数组转成树
循环
/*** 把平铺的数组结构转成树形结构** [* {id:"01", pid:"", "name":"老王" },* {id:"02", pid:"01", "name":"小张" }* ]* 上面的结构说明: 老王是小张的上级* @param {*} list* @returns*/// [// { 'id': '3129', 'pid': '', 'name': '总裁办' },// { 'id': '312a', 'pid': '', 'name': '行政部' },// { 'id': '312b', 'pid': '', 'name': '人事部' },// { 'id': '312c', 'pid': '', 'name': '财务部' },// { 'id': '312d', 'pid': '312c', 'name': '财务核算部'},// { 'id': '312e', 'pid': '312c', 'name': '税务管理部'},// { 'id': '312f', 'pid': '312c', 'name': '薪资管理部'},// { 'id': '00d2', 'pid': '', 'name': '技术部'},// { 'id': '00d3', 'pid': '00d2', 'name': 'Java研发部' },// { 'id': '00d4', 'pid': '00d2', 'name': 'Python研发部'},// { 'id': '00d5', 'pid': '00d2', 'name': 'Php研发部'},// { 'id': '00d6', 'pid': '', 'name': '运营部' },// { 'id': '00d7', 'pid': '', 'name': '市场部'},// { 'id': '00d8', 'pid': '00d7', 'name': '北京事业部'},// { 'id': '00d9', 'pid': '00d7', 'name': '上海事业部'}// ]export function tranListToTreeData(list) {// 最终要产出的树状数据的数组const treeList = []// 所有项都使用对象存储起来const map = {}// 建立一个映射关系:通过id快速找到对应的元素list.forEach(item => {if (!item.children) {item.children = []}map[item.id] = item})// map:// {// "312c": { 'id': '312c', 'pid': '', 'name': '财务部', children: [{ 'id': '312d', 'pid': '312c', 'name': '财务核算部',children: []}] },// "312d": { 'id': '312d', 'pid': '312c', 'name': '财务核算部',children: []}// }list.forEach(item => {// 对于每一个元素来说,先找它的上级// 如果能找到,说明它有上级,则要把它添加到上级的children中去// 如果找不到,说明它没有上级,直接添加到 treeListconst parent = map[item.pid]// 如果存在则表示item不是最顶层的数据if (parent) {parent.children.push(item)} else {// 如果不存在 则是顶层数据treeList.push(item)}})// 返回出去return treeList}
递归

递归组装树型结构的思路:
- 对定的数组和父id, 通过filter找出它的children ```javascript const arr = [ { ‘id’: ‘3129’, ‘pid’: ‘’, ‘name’: ‘总裁办’ }, { ‘id’: ‘312a’, ‘pid’: ‘’, ‘name’: ‘行政部’ }, { ‘id’: ‘312b’, ‘pid’: ‘’, ‘name’: ‘人事部’ }, { ‘id’: ‘312c’, ‘pid’: ‘’, ‘name’: ‘财务部’ }, { ‘id’: ‘312d’, ‘pid’: ‘312c’, ‘name’: ‘财务核算部’ }, { ‘id’: ‘312e’, ‘pid’: ‘312c’, ‘name’: ‘税务管理部’ }, { ‘id’: ‘312f’, ‘pid’: ‘312c’, ‘name’: ‘薪资管理部’ }, { ‘id’: ‘00d2’, ‘pid’: ‘’, ‘name’: ‘技术部’ }, { ‘id’: ‘00d3’, ‘pid’: ‘00d2’, ‘name’: ‘Java研发部’ }, { ‘id’: ‘00d4’, ‘pid’: ‘00d2’, ‘name’: ‘Python研发部’ }, { ‘id’: ‘00d5’, ‘pid’: ‘00d2’, ‘name’: ‘Php研发部’ }, { ‘id’: ‘00d6’, ‘pid’: ‘’, ‘name’: ‘运营部’ }, { ‘id’: ‘00d7’, ‘pid’: ‘’, ‘name’: ‘市场部’ }, { ‘id’: ‘00d8’, ‘pid’: ‘00d7’, ‘name’: ‘北京事业部’ }, { ‘id’: ‘00d9’, ‘pid’: ‘00d7’, ‘name’: ‘上海事业部’ } ]
function f(arr, root = ‘312c’) { const ar = arr.filter(item => item.pid == root) ar.forEach(item => { item.children = f(arr, item.id) }) return ar }
console.dir(f(arr))
上面的f函数中,每一个轮次的递归都会对整个arr进行循环,进一步对递归的部分做优化:每轮过滤之后,从arr中排除出来被选中的内容,将arr的规模减少。```javascriptfunction f(arr, root = '') {console.log(arr.length, root)const ar = []for(let i = 0; i< arr.length; i++) {if(arr[i].pid === root) {ar.push(...arr.splice(i--, 1))}}ar.forEach(item => {console.log(arr, item)item.children = f(arr, item.id)})return ar}console.dir(f(arr))
从树状组件中查找某个元素
var arr = [{label: '张大大',children: [{label: '小亮',children: [{ label: '小丽' }, { label: '大光' }]},{label: '小美',children: [{ label: '小高' }]},{label: '老马',children: [{ label: '小刘' }, { label: '小华' }, { label: '小李' }]},{label: '老王',children: [{ label: '小赵' }, { label: '小强', children: [{ label: '小赵1', children: [{ label: '小赵22' }, { label: '小强23' }] }, { label: '小强2' }] }]},{label: '老李',children: [{ label: '小涛' }]}]}]function f(arr, label = '张大大') {if (arr.length === 0) {return null} else {const rs = arr.find(item => item.label === label)if (rs) {return rs} else {const r = []arr.forEach(item => {if (item.children) {r.push(...item.children)}})return f(r, label)}}}console.log(f(arr, '老王'))
