I have an array that looks like this:
const arr = [
{
parent: 'A',
children: ['B'],
},
{
parent: 'B',
children: ['C'],
},
{
parent: 'C',
children: ['D']
}];
and I want to create a function that will take this array and result in the following object:
const result = {
parent: 'A',
children: [{
parent: 'B',
children: [{
parent: 'C',
children: [{
parent: 'D',
children: []
}]
}]
}]
};
so the result type would look like:
type Result = {
parent: string;
children: Result[];
};
What I've tried so far:
type TInput = {
parent: string;
children: string[];
};
type Result = {
parent: string;
children: Result[];
};
// can assume we know initial parent is 'A'
const fn = (parent: string, inputArr: TInput[]) => {
const result: TResult[] = [];
let newParent: string[] = [];
while (newParent.length !== 0) {
const index = inputArr.findIndex(
(input) => input.parent === parent
);
result.push({
parent: inputArr[index].parent,
children: [], // need to populate on next pass?
});
newParent = inputArr[index].children;
}
return result;
};
I don't know how many objects will be in the input array, but can assume first object is known to be initial parent/child ('A' in the example). Any help much appreciated. Thanks
I'd use a parent map to recreate children attribute as arrays of parent objects:
const arr = [
{
parent: 'A',
children: ['B'],
},
{
parent: 'B',
children: ['C'],
},
{
parent: 'C',
children: ['D']
},
{
parent: 'D',
children: []
}
];
const makeTree = (manyParents,rootName) => {
// copy parent objects into a map.
let mapIt = new Map(manyParents.map(pObject => {
return [pObject.parent, pObject];
}));
// recreate children arrays for each parents.
mapIt.forEach((oneParent) => {
let newChildrenArray = [];
//find every children objects.
oneParent.children.forEach((oneChild) => {
newChildrenArray.push(mapIt.get(oneChild));
});
//replace children array.
oneParent.children = newChildrenArray;
});
return mapIt.get(rootName);
}
let tree = makeTree(arr,'A');
console.log(tree)