stackuser
stackuser

Reputation: 374

How to find the count of some object property in array of objects using react and javascript?

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

Answers (4)

Amila Senadheera
Amila Senadheera

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

Ram Rana
Ram Rana

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

3limin4t0r
3limin4t0r

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

Akshay Mathur
Akshay Mathur

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

Related Questions