Reputation: 374
Hi below is the array of objects.
const arr_obj = [
{
id: '1',
children: [],
type: 'TYPE1',
},
{
id: '2',
children: [
{
id: '1',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '2',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '3',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
]
type: 'TYPE2',
},
{
id: '3',
children: [
{
id: '4',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '5',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
{
id: '6',
children: [
{
//some attributes
}
],
type: 'MAIN',
},
]
type: 'TYPE2',
}
]
I have to find out the count of type: 'MAIN'. these 'MAIN' will be within type: "type2"
So the expected count is 6. The outer children array can be empty and sometimes inner children array with type: "type2" is not there at all examples like below:
children: [] //empty array
children: [
{
id: '1',
children: [],
type: 'TYPE2',
},
] //no children with type: 'TYPE2'
below is the code to handle above,
const findCount = (arr_obj) => {
let count = 0;
const expectedCount = 2;
const loop = (children) => {
for (const obj of children) {
const { type, children } = obj;
if (type === 'TYPE2') {
loop(children);
} else if (type === 'MAIN') {
++count;
}
}
};
loop(children);
return count > expectedCount;
};
const output = findCount(arr_obj);
the above works fine. but it doesnt handle case when inner children is [] like below,
children: [
{
id: '1',
children: [],
type: 'TYPE2',
},
] //no children for type: 'TYPE2'
how can i handle the above data with no inner children array for children of type "TYPE2". could someone help me with this. thanks.
Upvotes: 1
Views: 972
Reputation: 13235
I modified the example by adding another valid occurrence in the nested object.
The following would also work.
// count the occurences of typeX as the very next of typeY
const count_TypeX_Within_TypeY = (arr, typeX, typeY) => {
let count = 0;
arr.forEach((item) => {
// check the type in current level
if (item.type === typeY) {
item.children.forEach((innerItem) => {
// // check the type in next level
if (innerItem.type === typeX) {
count += 1;
}
});
}
// do the same recursively
count += count_TypeX_Within_TypeY(item.children || [], typeX, typeY);
});
return count;
};
const arr_obj = [{"id":"1","children":[],"type":"TYPE1"},{"id":"2","children":[{"id":"1","children":[{}],"type":"MAIN"},{"id":"2","children":[{}],"type":"MAIN"},{"id":"3","children":[{}],"type":"MAIN"}],"type":"TYPE2"},{"id":"3","children":[{"id":"4","children":[{}],"type":"MAIN"},{"id":"5","children":[{"id":"7","type":"TYPE2","children":[{"id":"8","type":"MAIN","children":[{}]}]}],"type":"MAIN"},{"id":"6","children":[{}],"type":"MAIN"}],"type":"TYPE2"}];
console.log(count_TypeX_Within_TypeY(arr_obj, "MAIN", "TYPE2"));
Upvotes: 0
Reputation: 204
let count = 0;
arr_obj.?.filter(item=> item.type =="TYPE2").forEach((item)=> {
if(item.children.length > 0){
item.children.forEach((childItem)=>{
if(childItem.type == "MAIN"){
count+=1;
}
})
}
})
console.log(count);// output will be 6
Upvotes: 0
Reputation: 21110
how can i handle the above data with no inner children array for children of type "TYPE2".
You could add a guard clause to your loop
function:
if (!children) return;
Which returns directly if there are no children.
Resulting in:
const findCount = (arr_obj) => {
let count = 0;
const expectedCount = 2;
const loop = (children) => {
if (!children) return;
for (const obj of children) {
const { type, children } = obj;
if (type === 'TYPE2') {
loop(children);
} else if (type === 'MAIN') {
++count;
}
}
};
loop(arr_obj); // <- this should probably refer to `arr_obj`
return count > expectedCount;
};
const output = findCount(arr_obj);
Upvotes: 1
Reputation: 501
For no inner children, you can check if the array of children has any elements in it or not. Something like this
const loop = (children) => {
for (const obj of children) {
const { type, children } = obj;
if (type === 'TYPE2' && children.length > 0) {
loop(children);
} else if (type === 'MAIN') {
++count;
}
}
};
Upvotes: 0