代码实现

/**
 * MAP数组转换树形结构
 * 例:
 * arrayToTreeBy(array, (a, b) => {
 *     return a.pid == b.id // a 是属于 b 的子集内
 * })
 *
 *
 * @param array MAP数组
 * @param iteratee 迭代器,iteratee 会调用两个个参数: a(当前项) 和 b(比较项), 返回的值作为 a 是属于 b 的子集内
 * @param childrensKey 存放子集的Key默认:'children'
 * @returns 树形结构数组
 */
const arrayToTreeBy = function (array, iteratee, childrensKey) {
    if (typeof childrensKey === 'undefined') childrensKey = 'children'
    array.splice(0, array.length, ...array.filter((item, i) => {
        const parent = array.find(compare => iteratee(item, compare));
        if (parent) {
            if (!Array.isArray(parent[childrensKey])) {
                parent[childrensKey] = [];
            }
            parent[childrensKey].push(item);
            return false;
        }
        return true;
    }));
    return array;
};

/**
 * MAP数组转换树形结构
 * 例:
 * arrayToTreeBy(array, 'pid', 'id')
 *
 *
 * @param array MAP数组
 * @param akey a (当前项)的 Key
 * @param bKey b (比较项)的 Key
 * @param childrensKey 存放子集的Key
 * @returns 树形结构数组
 */
const arrayToTree = function (array, akey, bKey, childrensKey) {
    return arrayToTreeBy(array, (a, b) => a[akey] == b[bKey], childrensKey);
};

使用方法

测试数据

// 数据源
const data = [
    {"id":1,"name":"根节点1","pid":"0"},
    {"id":2,"name":"金字塔1","pid":"1"},
    {"id":3,"name":"金字塔2","pid":"1"},
    {"id":6,"name":"金字塔2-1","pid":"3"},
    {"id":5,"name":"金字塔1-1","pid":"2"},
    {"id":8,"name":"金字塔1-1-1","pid":"5"},
    {"id":9,"name":"金字塔2-1-1","pid":"6"},
    {"id":10,"name":"金字塔1-1-1-1","pid":"8"},
    {"id":11,"name":"金字塔1-2","pid":"2"},
    {"id":12,"name":"金字塔1-2-1","pid":"11"},
    {"id":13,"name":"金字塔1-2-1-1","pid":"12"},
    {"id":14,"name":"金字塔2-2","pid":"3"},
    {"id":15,"name":"金字塔2-3","pid":"3"},
    {"id":16,"name":"金字塔2-4","pid":"3"},
    {"id":17,"name":"金字塔1-2-1-1","pid":"12"},
    {"id":18,"name":"金字塔1-1-2","pid":"5"},
    {"id":19,"name":"金字塔2-1-1-1","pid":"9"},
    {"id":20,"name":"金字塔2-1-1-2","pid":"9"},
    {"id":23,"name":"金字塔3","pid":"24"},
    {"id":24,"name":"根节点2","pid":"0"},
    {"id":25,"name":"金字塔4","pid":"24"},
    {"id":26,"name":"金字塔3-1","pid":"23"},
    {"id":27,"name":"金字塔4-1","pid":"25"},
    {"id":28,"name":"金字塔1-1-1-1-1","pid":"10"},
    {"id":29,"name":"金字塔1-1-1-1-1-1","pid":"28"},
    {"id":30,"name":"金字塔1-1-1-1-1-1-1","pid":"29"},
    {"id":31,"name":"金字塔1-1-2-1","pid":"18"},
    {"id":32,"name":"金字塔1-1-2-1-1","pid":"31"},
    {"id":33,"name":"金字塔1-1-2-1-1-1","pid":"32"}
];

使用 id 与 pid 进行匹配

// 使用 id 于 pid 进行匹配
const tree = arrayToTree(data, 'pid', 'id');

使用 代送器 进行匹配

// 使用 代送器 进行匹配
const tree = arrayToTreeBy(data, (a, b) => {
    return a.pid = b.id;
});