【面试】js数组结构转树结构

74 阅读1分钟

好吧,这道题今年看到了好多文章,有2种方式,一种是递归,一种是非递归解决。例如我们数据如下:

var arr = [
    { 'id': '29', 'pid': '0', 'name': '总裁办' },
    { 'id': '2c', 'pid': '0', 'name': '财务部' },
    { 'id': '2d', 'pid': '2c', 'name': '财务核算部' },
    { 'id': '2f', 'pid': '2c', 'name': '薪资管理部' },
    { 'id': 'd2', 'pid': '0', 'name': '技术部' },
    { 'id': 'd3', 'pid': 'd2', 'name': 'Java研发部' }
]

解法1 递归解法

function arrayToTree(array, pid) {
    const nodes = array.filter(item => item.pid === pid);
    for (let i = 0; i < nodes.length; i++) {
        const item = nodes[i];
        item.children = arrayToTree(array, item.id);
    }
    return nodes;
}

arrayToTree(arr, '0');

挺简洁的吧,但就是每次都要遍历所有的节点找子节点,效率不高。

解法2 非递归解法

  1. 先把所有数据按照id为key存到map结构中
  2. 遍历所有的数据,如果map中有pid对应的节点,则说明有父节点,如果父节点还没有孩子节点,则创建孩子节点放进去,否则push到子孩子中。
function arrayToTree2(array) {
    let result = [];
    if (!Array.isArray(array)) {
        return result;
    }
    const map = {};
    array.forEach(item => map[item.id] = item);

    array.forEach(item => {
        const parent = map[item.pid];
        if (parent) {
            if (!parent.children) {
                parent.children = [item];
            } else {
                parent.children.push(item)
            }
        } else {
            result.push(item);
        }
    })
    return result;
}

arrayToTree2(arr);

完结撒花🎉。水了一篇,虽然写的都挺水的哈哈哈,所以主要还是笔记形式呀。