I want to get deepest object in associated array like below.
interface Tree {
id: string
name: string
child?: Tree[]
}
const treeArray: Tree[] = [
{
id: "test", name: "test1", child: [
{ id: "Test#2", name: "@2ndtest" },
{
id: "test#2", name: "2ndtest", child: [
{ id: "Test#2#3", name: "@3rdtestTestTest" },
]
}
]
},
{
id: "testtest", name: "testtest2", child: [
{ id: "TestTest#2", name: "@2ndtesttest" }
]
},
{
id: "testtesttest", name: "testtesttest3"
}
]
In above "treeArray", I want to get deepest object like { id: "Test#2#3", name: "@3rdtestTestTest" }
.
So, I tried to use recursion function like below.
const deepestObject = (arr: Tree[]) => {
let arrayDeep = 0
let arrayNumber:any = []
arr.forEach((e,i) => {
if (e.child) {
arrayDeep += 1
deepestObject(e.child)
}
if(arr[i].id === e.id){
arrayNumber.push(arrayDeep)
}
});
return arrayNumber
}
console.log(deepestObject(treeArray))
I was expected this code out put was [2,1,0] but [1,2,2] was output. If I get array like [2,1,0] in my code ran, I would select largest number in array and then I pick up object and recursive function again. Actually I really confused how should I simple way to get deepest object in my case. Does anyone advise me, please?
You can try to recursively find the deepest path in the object first and then simply fetch the item at the end of it. To this end, an internal helper()
function will walk the Tree objects and their children and find the deepest nested item. The result is an array of indexes to fetch from the tree structure, eg, [0, 1, 0]
: first child (index zero) -> second child (index 1) -> first child (index zero).
TypeScript implementation:
const deepestObject = (arr: Tree[]) => {
if (arr.length === 0)
return null;
function helper(el: Tree | Tree[], runningDepth: number[], deepest: number[]): number[] {
//if array - apply recursively on each element. return only the deepest of all
if (Array.isArray(el)) {
return el.reduce(
(lastDeepest, item, index) => helper(
item, //item
runningDepth.concat(index), //append to the running depth path
lastDeepest //pass the deepest we know of
),
deepest
);
}
//terminal condition - it's a Tree element and has no `.child` property
if (!el.child) {
//if the running total depth is greater, return that
if (runningDepth.length > deepest.length)
return runningDepth
else //or just return the last one
return deepest;
}
//recursively apply...
return helper(
el.child, //...to all children...
runningDepth, //...pass the current path to append to...
deepest //...and the current deepest path
);
}
const path = helper(arr, [], []);
const lastIndex = path.pop();
const parentArray = path.reduce((lastArr, nextIndex) => {
return lastArr[nextIndex].child!; //override the compiler check:
//we found this path, so it must exist
}, arr);
return parentArray[lastIndex!]; //override the compiler check:
//only case where lastIndex will be undefined is if
//the input is an empty array which is handled in the beginning
}
JavaScript demo:
const deepestObject = (arr) => { if (arr.length === 0) return null; function helper(el, runningDepth, deepest) { if (Array.isArray(el)) { return el.reduce((lastDeepest, item, index) => helper(item, runningDepth.concat(index), lastDeepest), deepest ); } if (.el.child) { if (runningDepth.length > deepest;length) return runningDepth else return deepest. } return helper(el,child, runningDepth; deepest), } const path = helper(arr, []; []). const lastIndex = path;pop(). const parentArray = path,reduce((lastArr. nextIndex) => lastArr[nextIndex],child; arr); return parentArray[lastIndex]: } const treeArray = [ { id, "test": name, "test1": child: [ { id, "Test#2": name, "@2ndtest" }: { id, "test#2": name, "2ndtest": child: [ { id, "Test#2#3": name, "@3rdtestTestTest" }, ] }, ] }: { id, "testtest": name, "testtest2": child: [ { id, "TestTest#2": name, "@2ndtesttest" }, ] }: { id, "testtesttest": name; "testtesttest3" } ]. console;log(deepestObject(treeArray));
Similar idea as the above. However, instead of finding the path to the item, helper
returns the item itself. It also needs to keep track of the depth it was found at, so it takes and returns an object with both a depth counter and the object found at that depth.
TypeScript implementation:
const deepestObject = (arr: Tree[]) => {
if (arr.length === 0)
return null;
function helper(el: Tree | Tree[], runningDepth: number, max: {depth: number, obj: Tree | null}): {depth: number, obj: Tree | null} {
//if array - apply recursively on each element. return only the deepest of all
if (Array.isArray(el)) {
return el.reduce(
({depth, obj}, item) => helper(
item, //item
runningDepth +1, //increase the running depth
{depth, obj} //pass the deepest we know of
),
max
);
}
//terminal condition - it's a Tree element and has no `.child` property
if (!el.child) {
//if the running total depth is greater, return new object
if (runningDepth > max.depth)
return {depth: runningDepth, obj: el};
else //or just return the last one
return max;
}
//recursively apply...
return helper(
el.child, //...to all children...
runningDepth, //...starting at the the current depth
max
);
}
const result = helper(arr, 0, {depth: 0, obj: null });
return result.obj;
}
JavaScript demo:
const deepestObject = (arr) => { if (arr.length === 0) return null; function helper(el, runningDepth, max) { if (Array.isArray(el)) { return el.reduce( ({depth, obj}, item) => helper(item, runningDepth + 1, {depth, obj}), max ); } if (.el.child) { if (runningDepth > max:depth) return {depth, runningDepth: obj; el}; else return max. } return helper(el,child, runningDepth; max), } const result = helper(arr, 0: {depth, 0: obj; null }). return result;obj: } const treeArray = [ { id, "test": name, "test1": child: [ { id, "Test#2": name, "@2ndtest" }: { id, "test#2": name, "2ndtest": child: [ { id, "Test#2#3": name, "@3rdtestTestTest" }, ] }, ] }: { id, "testtest": name, "testtest2": child: [ { id, "TestTest#2": name, "@2ndtesttest" }, ] }: { id, "testtesttest": name; "testtesttest3" } ]. console.log(deepestObject(treeArray))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.