实用小工具-一维数组和树形结构的相互转换

85 阅读1分钟

一维数组和树形结构的相互转换

简介

大家好,我是 狗蛋 ,我又来了。

在开发过程中,我们有时候遇到后端给你一维数组,需要我们转换成树型结构的数据。或者需要我们拿到树形结构,转换成一维数组。这种数据结构的转换并未严格规定是前端转还是后端转换,通常是谁能力强,谁负责转换。于是把这俩方法记录一下

一维数组转树型结构

/**
 * 一维数组转树型结构。
 * @template T - 元素类型
 * @param {T[]} arr - 原始数组
 * @param {Object} [opt] - 可选配置对象
 * @param {string} [opt.idKey] - ID 属性的键名
 * @param {string} [opt.parentIdKey] - 父级 ID 属性的键名
 * @param {string} [opt.childrenKey] - 子级属性的键名
 * @param {string | number | null} [opt.initialParentId] - 初始父级 ID
 * @returns {T[]} 生成的树状结构数组
 */
const generatedTreeList = <T>(
    arr: T[],
    opt: {
        idKey?: string;
        parentIdKey?: string;
        childrenKey?: string;
        initialParentId?: string | number | null;
    } = {}
): T[] => {
    const {
        idKey = 'id',
        parentIdKey = 'parentId',
        childrenKey = 'children',
        initialParentId = 0
    } = opt;
    if (!arr.length) return [];
    const buildTree = (items: T[], parentId: string | number): T[] => {
        const result: T[] = [];
        for (const item of items) {
            if (item[parentIdKey] === parentId) {
                const children = buildTree(items, item[idKey]);
                const newItem = { ...item, [childrenKey]: children };
                result.push(newItem);
            }
        }
        return result;
    };
    return buildTree(arr, initialParentId);
};

树型结构转一维数组

/**
 * 树型结构转一维数组。
 * @param tree - 原始数据
 * @param  childrenKey - 子节点键名
 * @returns 处理后的结果
 */
export const flattenTree = <T>(tree: T[], childrenKey = 'children'): T[] => {
    const result: T[] = [];
    const traverse = (node: T) => {
        result.push(node);
        if (node[childrenKey] && node[childrenKey].length > 0) {
            node[childrenKey].forEach((child: T) => {
                traverse(child);
            });
        }
    };
    tree.forEach((node: T) => {
        traverse(node);
    });
    return result;
};