export class TreeHelper {
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'
) {
const map = {};
const tree = items.reduce((prev: T[], curr: S) => {
const tmp = objectMapper ? objectMapper(curr) : curr;
const newItem: any = { ...tmp } as T;
const id = idMapper(curr);
newItem[childrenProperty] = map.hasOwnProperty(id) ? map[id][childrenProperty] : [];
map[id] = newItem;
let parentId = parentIdMapper(curr);
if (!parentId) {
prev.push(newItem);
} else {
if (!map.hasOwnProperty(parentId)) {
map[parentId] = {};
map[parentId][childrenProperty] = [];
}
map[parentId][childrenProperty].push(newItem);
}
return prev;
}, []);
return tree;
}
}