I have an array of objects of unknown depth as follows:
var mainArray = [
{
"Application": "noun",
"Dependencies": [
{
"Application": "ant"
},
{
"Application": "ball"
},
{
"Application": "cat"
},
{
"Application": "dog"
},
{
"Application": "insect",
"Dependencies": [
{
"Application": "cat"
},
{
"Application": "lion"
}
]
},
{
"Application": "goat"
},
{
"Application": "horse"
},
{
"Application": "insect",
"Dependencies": {
"Application": "ant"
}
},
{
"Application": "jaguar"
},
{
"Application": "kite"
},
{
"Application": "lion"
},
{
"Application": "monkey",
"Dependencies": {
"Application": "dog",
"Dependencies": [
{
"Application": "ant",
"Dependencies": [
{
"Application": "bell"
},
{
"Application": "boar"
},
{
"Application": "king",
"Dependencies": {
"Application": "lion"
}
},
{
"Application": "pig"
},
{
"Application": "skunk",
"Dependencies": [
{
"Application": "cat"
},
{
"Application": "rat"
},
{
"Application": "boar",
"Dependencies": {
"Application": "dog",
"Dependencies": [
{
"Application": "apple",
"Dependencies": [
{
"Application": "tree"
},
{
"Application": "lion"
}
]
},
{
"Application": "animal",
"Dependencies": [
{
"Application": "rat"
},
{
"Application": "boar"
},
{
"Application": "kite"
}
]
}
]
}
},
{
"Application": "ball"
},
{
"Application": "rat"
}
]
},
{
"Application": "nice"
},
{
"Application": "soap"
},
{
"Application": "new",
"Dependencies": [
{
"Application": "cot"
},
{
"Application": "bed"
}
]
},
{
"Application": "house"
}
]
},
{
"Application": "things",
"Dependencies": [
{
"Application": "dress"
},
{
"Application": "pant"
},
{
"Application": "shoe"
},
{
"Application": "tie"
},
{
"Application": "shirt"
}
]
}
]
}
}
]
},
{
"Application": "pronoun",
"Dependencies": [
{
"Application": "ant"
},
{
"Application": "cat"
},
{
"Application": "dog"
},
{
"Application": "lion"
},
{
"Application": "insect"
}
]
}
]
I need to find the maximum depth of the property values like ant
, ball
, cat
etc. in the array of objects.
In the above array of objects, I have two objects namely noun
and pronoun
. I need to find the maximum depth of each property value in the noun
and pronoun
objects.
For example, if we take "Application": "noun"
as level 1, then the value ant
occurs first at level 2, then at level 3 and lastly at level 4 in the noun
object. So, the maximum depth of ant
in the noun
object is 4. Similarly, the same ant
value occurs at level 2 in the pronoun
object. So, the maximum depth of ant
in pronoun
object is 2. This way, I need to find the maximum depth of all the values(ant,ball,cat,dog,insect,lion etc etc).
The desired output should be as follows:
[
{
"value": "ant",
"enrichment": {
"applicationTier": "noun:4, pronoun:2, default:4"
},
"attribute": "application_tier"
},
{
"value": "ball",
"enrichment": {
"applicationTier": "noun:6, default:6"
},
"attribute": "application_tier"
},
{
"value": "cat",
"enrichment": {
"applicationTier": "noun:6, pronoun:2, default:6"
},
"attribute": "application_tier"
},
{
"value": "dog",
"enrichment": {
"applicationTier": "noun:7, pronoun:2, default:7"
},
"attribute": "application_tier"
},
{
"value": "insect",
"enrichment": {
"applicationTier": "noun:2, pronoun:2, default:2"
},
"attribute": "application_tier"
},
{
"value": "lion",
"enrichment": {
"applicationTier": "noun:9, pronoun:2, default:9"
},
"attribute": "application_tier"
}
.......
.......
.......
.......
]
In the above output, the enrichment
object indicates the maximum depth of the properties in the noun
and pronoun
objects. Here, default
is the maximum depth among the noun
and pronoun
depths. The only thing is that the output should be exactly like the above output. Please help.
CodePudding user response:
Presented below is one possible way to achieve the desired objective.
Code Snippet
// helper method - recursively count depth
const recurCount = (dep, type, currRes, level) => {
// de-structure to access app & dep
const { Application, Dependencies = null } = dep;
// logical nullish assignment of app, noun/pronoun, default
currRes[Application] ??= {};
currRes[Application][type] ??= level 1;
currRes[Application].default ??= level 1;
// if noun or pronound depth "level" is higher, update it
if (currRes[Application][type] <= level) {
currRes[Application][type] = level 1;
};
// update "default" is depth "level" is higher
if (currRes[Application].default <= level) {
currRes[Application].default = level 1;
};
// if dep is not null
if (Dependencies) {
if (Array.isArray(Dependencies)) { // dep is an array
return Dependencies.reduce( // use ".reduce" to iterate & get result
(acc, depElt) => ({
...acc,
...recurCount( // recursive call for nested dep
depElt, type, currRes, level 1
)
}),
currRes // initially set to current-result
)
} else if (typeof Dependencies === 'object') { // dep is an object
return {
...currRes,
...recurCount( // recursive call for nested dep
Dependencies, type, currRes, level 1
)
};
}
};
// if no conditions met, do not recurse.
// simply return current result object
return currRes;
};
// helper method to "sort" the "enrichments"
// to match the "noun:x, pronoun:y, default:z" format
const mySort = ([ak], [bk], list) => {
const newList = [...list, 'default'];
return newList.indexOf(ak) - newList.indexOf(bk);
};
// the main depth-counter method
const myCounter = (arr, list) => (
Object.entries( // transform intermediate result-object into array
arr
.filter( // filter to keep only noun, pronoun
({ Application }) => list.includes(Application)
)
.reduce( // iterate for noun, pronoun dep-arrays
(fin, { Application, Dependencies }) => ({
...fin,
...( // for each dep-array, iterate over its elements
Dependencies.reduce(
(acc, depElt) => ({
...acc,
...recurCount(depElt, Application, fin, 1)
}),
fin
)
)
}),
{}
)
).map( // transform key-value array to desired objective format
([value, vobj]) => ({
value,
"enrichment": {
applicationTier: Object.entries(vobj)
.sort((a, b) => mySort(a, b, list))
.map(
([k, v]) => `${k}:${v}`
).join(', ')
},
"attribute": "application_tier"
})
)
);
// given array
const mainArray = [{
"Application": "noun",
"Dependencies": [{
"Application": "ant"
},
{
"Application": "ball"
},
{
"Application": "cat"
},
{
"Application": "dog"
},
{
"Application": "insect",
"Dependencies": [{
"Application": "cat"
},
{
"Application": "lion"
}
]
},
{
"Application": "goat"
},
{
"Application": "horse"
},
{
"Application": "insect",
"Dependencies": {
"Application": "ant"
}
},
{
"Application": "jaguar"
},
{
"Application": "kite"
},
{
"Application": "lion"
},
{
"Application": "monkey",
"Dependencies": {
"Application": "dog",
"Dependencies": [{
"Application": "ant",
"Dependencies": [{
"Application": "bell"
},
{
"Application": "boar"
},
{
"Application": "king",
"Dependencies": {
"Application": "lion"
}
},
{
"Application": "pig"
},
{
"Application": "skunk",
"Dependencies": [{
"Application": "cat"
},
{
"Application": "rat"
},
{
"Application": "boar",
"Dependencies": {
"Application": "dog",
"Dependencies": [{
"Application": "apple",
"Dependencies": [{
"Application": "tree"
},
{
"Application": "lion"
}
]
},
{
"Application": "animal",
"Dependencies": [{
"Application": "rat"
},
{
"Application": "boar"
},
{
"Application": "kite"
}
]
}
]
}
},
{
"Application": "ball"
},
{
"Application": "rat"
}
]
},
{
"Application": "nice"
},
{
"Application": "soap"
},
{
"Application": "new",
"Dependencies": [{
"Application": "cot"
},
{
"Application": "bed"
}
]
},
{
"Application": "house"
}
]
},
{
"Application": "things",
"Dependencies": [{
"Application": "dress"
},
{
"Application": "pant"
},
{
"Application": "shoe"
},
{
"Application": "tie"
},
{
"Application": "shirt"
}
]
}
]
}
}
]
},
{
"Application": "pronoun",
"Dependencies": [{
"Application": "ant"
},
{
"Application": "cat"
},
{
"Application": "dog"
},
{
"Application": "lion"
},
{
"Application": "insect"
}
]
}
];
// list of values used as "enrichments"
const listOfEnrichments = ["noun", "pronoun"];
// call the depth-counter method & console.log result array
console.log('depth-counted result array: ', myCounter(mainArray, listOfEnrichments));
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added to the snippet above.