2
作为前端, 不用算法也可以写成项目. 但是如果明白会算法的话, 你写起代码来会更得心应手.
无限分类递归 多数用在树形结构数据. 有这样一组数据:
const arr = [
    {
        id: 4,
        name: '张三的儿子',
        parentId: 1
    },
    {
        id: 43,
        name: '张三的2儿子',
        parentId: 1
    },
    {
        id: 5,
        name: '李四的儿子',
        parentId: 2
    },
    {
        id: 6,
        name: '张三的儿子的儿子',
        parentId: 4
    },
    {
        id: 1,
        name: '张三',
        parentId: 0
    },
    {
        id: 2,
        name: '李四',
        parentId: 0
    },
    {
        id: 3,
        name: '王五',
        parentId: 0
    },
];

想要得到的结果是这样子的:

const result = [
    {
        id: 1,
        name: '张三',
        parentId: 0,
        children: [
            {
                id: 4,
                name: '张三的儿子',
                parentId: 1,
                children: [
                    {
                        id: 6,
                        name: '张三的儿子的儿子',
                        parentId: 4
                    }
                ]
            },
            {
                id: 43,
                name: '张三的2儿子',
                parentId: 1
            }
        ]
    },
    {
        id: 2,
        name: '李四',
        parentId: 0,
        children: [
            {
                id: 5,
                name: '李四的儿子',
                parentId: 2
            }
        ]
    },
    {
        id: 3,
        name: '王五',
        parentId: 0
    }
];

这里我有两种做法:

  1. 递归
  2. 充分利用数据的引用(堆栈)

第一种:

function rescurve(arr, id) {
    let treeData = [];
    arr.forEach(i => {
        if(i.parentId == id) {
            treeData.push(i);
            i.children = rescurve(arr, i.id);
        }
    });
    return treeData;
};
console.log(rescurve(arr, 0)); // 输出正确的值

这种方法没什么说的 就是执行自身递归出想要的结构.

第二种:

function setTreeData(arr) {
    let map = {}; // 构建map
    arr.forEach(i => {
        map[i.id] = i; // 构建以id为键 当前数据为值
    });

    let treeData = [];
    arr.forEach(child => {
        const mapItem = map[child.parentId]; // 获取当前数据的parentId是否存在map中

        if (mapItem) { // 存在则表示当前数据不是最顶层数据
        
            // 注意: 这里的map中的数据是引用了arr的它的指向还是arr, 当mapItem改变时arr也会改变
            (mapItem.children || ( mapItem.children = [] )).push(child); // 这里判断mapItem中是否存在children, 存在则插入当前数据, 不存在则赋值children为[]然后再插入当前数据
        } else { // 不存在则是组顶层数据
            treeData.push(child);
        }
    });

    return treeData;
};

console.log(setTreeData(arr)); // 输出正确的值

这里需要注意的是对象的引用, 利用对象的引用改变指向的arr的数据. 就得到想要的结构


伍陆柒
1.2k 声望25 粉丝

如果觉得我的文章对大家有用的话, 可以去我的github start一下[链接]