interface GroupedData {
data: any;
children: GroupedData[];
}
function groupData(originalArray: any[]): GroupedData[] {
// Convert all elements for GroupedData shape in an object
// having the id's as the keys
const tempObj: { [id: string]: GroupedData } = array.reduce(
(acc, item) =>
(acc = { ...acc, [item.id]: { data: item, children: [] } }),
{}
);
// put each child in the right parent's children array
originalArray.forEach((item: any) => {
if (item.parentId) {
tempObj[item.parentId].children.push(tempObj[item.id]);
}
});
// filter out all the GroupedData that has a valid data.parentId
// and convert the final result to an array
return Object.keys(tempObj)
.map((key: string) => (tempObj[key].data.parentId ? null : tempObj[key]))
.filter(Boolean);
}
Если вы хотите работать с более формальной типизированной структурой, опирающейся на ядро языка, вы можете объявить tempObj
как машинопись Map<string, GroupedData>
:
function groupData(originalArray: any[]): GroupedData[] {
// Convert all elements for GroupedData shape in a Map
// having the id's as the keys
const tempMap: Map<string, GroupedData> = new Map(
originalArray.map(item => [item.id, { data: item, children: [] }])
);
// put each child in the right parent's children array
originalArray.forEach((item: any) => {
if (item.parentId) {
tempMap.get(item.parentId).children.push(tempMap.get(item.id));
}
});
// filter out all the GroupedData that has a valid data.parentId
// and convert the final result to an array.
// In ES6, you have some Array static methods, like Array.from()
return Array.from(tempMap)
.map(([key,value]) => (value.data.parentId ? null : value))
.filter(Boolean);
}