(面试题)数组转树

304 阅读2分钟

给你一个对象数组将其转化为树

var treeList = [
    {
        title: '系统管理',
        parentName: '',
        pid: 0,
        id: 1,
    },
    {
        title: '角色新增',
        parentName: '角色管理',
        pid: 22,
        id: 221,
    },
    {
        title: '角色编辑',
        parentName: '角色管理',
        pid: 22,
        id: 222,
    },
    {
        title: '角色删除',
        parentName: '角色管理',
        pid: 22,
        id: 223,
    },
    {
        title: '用户新增',
        parentName: '用户管理',
        pid: 33,
        id: 331,
    },
    {
        title: '菜单新增',
        parentName: '菜单管理',
        pid: 11,
        id: 111,
    },
    {
        title: '菜单编辑',
        parentName: '菜单管理',
        pid: 11,
        id: 112,
    },
    {
        title: '用户管理',
        parentName: '系统管理',
        pid: 0,
        id: 33,
    },
    {
        title: '菜单管理',
        parentName: '系统管理',
        pid: 1,
        id: 11,
    },
    {
        title: '菜单删除',
        parentName: '菜单管理',
        pid: 11,
        id: 113,
    },
    {
        title: '用户编辑',
        parentName: '用户管理',
        pid: 33,
        id: 332,
    },
    {
        title: '角色管理',
        parentName: '系统管理',
        pid: 1,
        id: 22,
    },
    {
        title: '用户删除',
        parentName: '用户管理',
        pid: 33,
        id: 333,
    }
]

很容易想到使用递归的方法实现,数组中有一个很方便的方法就可以实现递归,那就是reduce

reduce()  方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。

const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  initialValue
);
console.log(sumWithInitial);
// expected output: 10

使用reduce函数,就能很容易的递归实现这种数组转树的操作

// answer
const array2tree = (array:any[],pid=0) => {
    return array.reduce((prev,next)=>{
        if(next.pid === pid ){
            const children = array2tree(array,next.id)
            if(children.length){
                next.children=children
            }
            prev.push(next)
        }
        return prev
    },[])
};
const res = array2tree(treeList)