export class TreeHelper {
/**
*
* @param items 扁平数据数组
* @param idMapper 数组元素的id映射
* @param parentIdMapper 数组元素的父节点id映射
* @param objectMapper 数组元素映射为另一种类型的对象,默认为undefined,即使用源对象类型
* @returns 树形数据数组
*/
public static arrayToTree<S, T>(
items: any[],
idMapper: (item: S) => string | number,
parentIdMapper: (item: S) => string | number,
objectMapper: (item: S) => T = undefined,
childrenProperty: string = 'children'
) {
// 已数据id为属性的map,用于暂存数据和快速存取父元素
const map = {};
// 使用数组的reduce过程,逐个循环,收敛结果到第一层数组
const tree = items.reduce((prev: T[], curr: S) => {
// 生成新的元素
const tmp = objectMapper ? objectMapper(curr) : curr;
const newItem: any = { ...tmp } as T;
// 对树形元素的子树数组赋值,
// 由于是一次循环,有可能在前面已经找到子节点,从而先创建了父节点,
// 所以如果在map中找到当前id为属性的节点,需要将子树合并过来
const id = idMapper(curr);
newItem[childrenProperty] = map.hasOwnProperty(id) ? map[id][childrenProperty] : [];
// 将当前节点放回map中
map[id] = newItem;
// 寻找找父节点
let parentId = parentIdMapper(curr);
if (!parentId) {
// 如果不存在父节点,则将当前节点放入第一层
prev.push(newItem);
} else {
// 如果存在父节点,则将当前节点放到父节点的子树中
if (!map.hasOwnProperty(parentId)) {
// 如果map中不存在父节点,则先创建一个临时的父节点
map[parentId] = {};
map[parentId][childrenProperty] = [];
}
map[parentId][childrenProperty].push(newItem);
}
// 返回第一层数组,继续归并下一个元素
return prev;
}, []);
return tree;
}
}
TypeScript应用数组reduce和对象map将扁平化数据转为树形结构
最新推荐文章于 2026-06-21 15:37:16 发布
该方法接受一个扁平数据数组,通过idMapper和parentIdMapper函数将数据转换为树形结构。它使用一个映射对象来存储和检索数据,同时支持自定义对象映射。最后,它将处理后的树形数据作为children属性返回。
629

被折叠的 条评论
为什么被折叠?



