Reputation: 2357
I have a JSON-like hierarchy of JS objects in the following format:
[
{
subs: [ ...other objects... ]
},
...other objects...
]
I wrote a method that returns the number of levels of such a hierarchy:
/* Returns the depth of the tree. */
public getDepth(): number {
function f(obj: object): number {
let depth = 0;
if (obj['subs'].length > 0) {
obj['subs'].forEach((s: object) => {
const tempDepth = f(s);
if (tempDepth > depth) depth = tempDepth;
});
}
return depth + 1;
}
if (this.tree.length > 0)
return Math.max(...this.tree.map((s: object) => f(s)));
else return 0;
}
It works but it's too complicated. Then, I've found this, much cleaner code: https://stackoverflow.com/a/16075976/5214911
The only difference is that I have not one base object but an array of objects as root. How could I simplify the code to spare that extra if and iteration?
Example data:
const data1 = []; // depth: 0
const data2 = [{}, {}, {}]; // depth: 1
const data3 = [{}, // depth: 5
{
"subs": [{
"subs": [{
"subs": [{}]
}, {
"subs": [{
"subs": [{}]
}]
}]
}, {
"subs": [{
"subs": [{}]
}]
}]
},
{}
];
Upvotes: 4
Views: 3466
Reputation: 386680
You could map the depth of every children and take the maximum value of it.
function getDepth(array) {
return 1 + Math.max(0, ...array.map(({ subs = [] }) => getDepth(subs)));
}
const
data1 = [],
data2 = [{}, {}, {}],
data3 = [{}, { subs: [{ subs: [{ subs: [{}] }, { subs: [{ subs: [{}] }] }] }, { subs: [{ subs: [{}] }] }] }, {}];
console.log(getDepth(data1) - 1); // 0
console.log(getDepth(data2) - 1); // 1
console.log(getDepth(data3) - 1); // 5
Upvotes: 9
Reputation: 36584
Use Array.prototype.map()
to change each item of array to its length and then use Math.max()
on array
getDepth = function (obj) {
var depth = 0;
if (obj.children) {
obj.children.forEach(function (d) {
var tmpDepth = getDepth(d)
if (tmpDepth > depth) {
depth = tmpDepth
}
})
}
return 1 + depth
}
let arr = [...];
let depths = arr.map(x => getDepth(x))
let maxDepth = Math.max(...depths)
Upvotes: 2