Reputation: 167
I have one array of nested objects. I want to edit each of them and add property "status" and value of this property can be "selected", "unselected" or "indent".
1. status: 'selected'
2. status: 'unselected'
3. status: 'indent'
all children means all nested children
Does anyone has idea how to do that?
let data = [{
id: 1,
name: 'level1',
lvlScope: [1, 2, 3],
lvl1Subs: []
},
{
id: 2,
name: 'level1',
lvlScope: [],
lvl1Subs: [{
id: 1,
name: 'level2',
lvlScope: [],
lvl2Subs: [{
id: 1,
name: 'level3',
lvlScope: [],
lvl3Subs: []
},
{
id: 2,
name: 'level3',
lvlScope: [1, 2],
lvl3Subs: []
},
{
id: 3,
name: 'level3',
lvlScope: [1],
lvl3Subs: [{
id: 1,
name: 'level4',
lvlScope: [],
lvl4Subs: [{
id: 1,
name: 'level5',
lvlScope: []
},
{
id: 2,
name: 'level5',
lvlScope: [1]
}
]
},
{
id: 2,
name: 'level4',
lvlScope: [],
lvl4Subs: []
}
]
}
]
},
{
id: 2,
name: 'level2',
lvlScope: [1],
lvl2Subs: []
}
]
},
{
id: 3,
name: 'level1',
lvlScope: [],
lvl1Subs: [{
id: 1,
name: 'level2',
lvlScope: [1, 2],
lvl2Subs: []
},
{
id: 2,
name: 'level2',
lvlScope: [],
lvl2Subs: []
},
{
id: 3,
name: 'level2',
lvlScope: [1, 2, 3],
lvl2Subs: [{
id: 1,
name: 'level3',
lvlScope: [],
lvl3Subs: []
}]
},
{
id: 4,
name: 'level2',
lvlScope: [],
lvl2Subs: []
},
{
id: 5,
name: 'level2',
lvlScope: [1, 2],
lvl2Subs: []
}
]
}
]
const levels = (data) => {
data.map((lvl1) => {
console.log('-lvl1', lvl1)
lvl1.lvl1Subs.map((lvl2) => {
console.log('--lvl2', lvl2)
lvl2.lvl2Subs.map((lvl3) => {
console.log('---lvl3', lvl3)
lvl3.lvl3Subs.map((lvl4) => {
console.log('----lvl4', lvl4)
lvl4.lvl4Subs.map((lvl5) => {
console.log('-----lvl5', lvl5)
})
})
})
})
})
}
console.log(levels(data))
Upvotes: 1
Views: 424
Reputation: 536
You didn't say anything about what to assign when the level has no children. Furthermore is not clear if the check should be done only to direct childs or also in the nested child. Here is a solution considering that no child means selected
or unselected
and considering the check only to direct childs.
const addStatus = (data, level = 1) => {
const scope = emptyScope(data);
let childrenScopes = [];
for (let child of data["lvl" + level + "Subs"]
? data["lvl" + level + "Subs"]
: []) {
childrenScopes.push(emptyScope(child));
addStatus(child, level + 1);
}
let status = "indent";
let found = childrenScopes.find((c) => c === !scope);
if (found === true || found === false) {
found = true;
} else {
found = false;
}
if ((!found || !childrenScopes.length) && !scope) {
status = "selected";
}
if ((!found || !childrenScopes.length) && scope) {
status = "unselected";
}
data["status"] = status;
};
const emptyScope = (data) => {
if (data.lvlScope.length > 0) {
return false;
}
return true;
};
data.map((d) => addStatus(d, 1));
console.log(data);
Edit after information was provided in comment
const addStatus = (data, level = 1) => {
const scope = emptyScope(data);
let childrenScopes = childScopes(data, level, []);
let status = "indent";
let found = typeof childrenScopes.find((c) => c === !scope) === "boolean";
if ((!found || !childrenScopes.length) && !scope) {
status = "selected";
}
if ((!found || !childrenScopes.length) && scope) {
status = "unselected";
}
data["status"] = status;
for (let child of data["lvl" + level + "Subs"]
? data["lvl" + level + "Subs"]
: []) {
addStatus(child, level + 1);
}
};
const childScopes = (data, level, scopes) => {
for (let child of data["lvl" + level + "Subs"]
? data["lvl" + level + "Subs"]
: []) {
scopes.push(emptyScope(child));
childScopes(data["lvl" + level + "Subs"], level, scopes);
}
return scopes;
};
const emptyScope = (data) => {
if (data.lvlScope.length > 0) {
return false;
}
return true;
};
data.map((d) => addStatus(d, 1));
console.log(data);
Upvotes: 1
Reputation: 648
you can easily solve this problem think in the way of a recursive function.
Upvotes: 0