to-tree-smart
Version:
A smart and efficient tree data structure converter that transforms flat arrays into hierarchical tree structures
82 lines (81 loc) • 2.57 kB
JavaScript
/**
* 将扁平数组转换为树形结构
* 使用 Map 数据结构实现 O(n) 时间复杂度
*
* @param data - 要转换的扁平数组
* @param options - 配置选项
* @returns 树形结构的根节点数组
*
* @example
* ```typescript
* const flatData = [
* { id: 1, name: 'Root', parentId: null },
* { id: 2, name: 'Child 1', parentId: 1 },
* { id: 3, name: 'Child 2', parentId: 1 },
* { id: 4, name: 'Grandchild', parentId: 2 }
* ];
*
* const tree = toTreeSmart(flatData);
* // 结果:
* // [
* // {
* // id: 1,
* // name: 'Root',
* // parentId: null,
* // children: [
* // {
* // id: 2,
* // name: 'Child 1',
* // parentId: 1,
* // children: [
* // { id: 4, name: 'Grandchild', parentId: 2 }
* // ]
* // },
* // { id: 3, name: 'Child 2', parentId: 1 }
* // ]
* // }
* // ]
* ```
*/
export function toTreeSmart(data, options = {}) {
const { idKey = 'id', parentIdKey = 'parentId', childrenKey = 'children', keepEmptyChildren = false, } = options;
// 使用 Map 构建节点映射,时间复杂度 O(n)
const nodeMap = new Map();
// 第一次遍历:初始化所有节点
data.forEach((item) => {
item[childrenKey] = []; // 初始化children为空数组
nodeMap.set(item[idKey], item);
});
const roots = [];
// 第二次遍历:构建树形结构
data.forEach((item) => {
const currentNode = nodeMap.get(item[idKey]);
const parentId = item[parentIdKey];
if (parentId !== null && parentId !== undefined && nodeMap.has(parentId)) {
// 有父节点,将当前节点添加到父节点的 children 中
const parentNode = nodeMap.get(parentId);
if (parentNode) {
parentNode[childrenKey].push(currentNode);
}
}
else {
// 没有父节点,说明是根节点
roots.push(currentNode);
}
});
// 如果不保留空的 children 数组,则递归删除
if (!keepEmptyChildren) {
const removeEmptyChildren = (node) => {
if (node[childrenKey] && node[childrenKey].length > 0) {
node[childrenKey].forEach(removeEmptyChildren);
}
else if (node[childrenKey] && node[childrenKey].length === 0) {
delete node[childrenKey];
}
};
roots.forEach(removeEmptyChildren);
}
return roots;
}
// 默认导出
export default toTreeSmart;