Recursively traverse an array of Objects based on their childrens “checked” state

I am trying to recursively uncheck all parent objects that have a child that is checked: false At the moment, my function is working for the direct parent of the child that is checked: false i.e “BSC Computer Science” is checked: flase meaning that “Computer Science” becomes checked: false aswell.

How do i loop over the original tree again when an item is being checked to false.

Expected output

    [
        {
            name: "College",
            checked: false,
            children: [
                { 
                    name: "College of engineering",
                    checked: false,
                    children: [
                        {
                            name: "Computer Science",
                            checked: false,
                            children: [
                                {
                                    name: "BSC Computer Science",
                                    checked: false,
                                }
                            ]
                        }
                    ]
                },
                { 
                    name: "Humanties",
                    checked: true,
                    children: [
                        {
                            name: "Humans",
                            checked: true,
                            children: [
                                {
                                    name: "HMS",
                                    checked: true,
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]

Thank you

const data = [
    {
        name: "College",
        checked: true,
        children: [
            { 
                name: "College of engineering",
                checked: true,
                children: [
                    {
                        name: "Computer Science",
                        checked: true,
                        children: [
                            {
                                name: "BSC Computer Science",
                                checked: false,
                            }
                        ]
                    }
                ]
            },
            { 
                name: "Humanties",
                checked: true,
                children: [
                    {
                        name: "Humans",
                        checked: true,
                        children: [
                            {
                                name: "HMS",
                                checked: true,
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

// If the bottom-most child segments are checked, also check the parent term
function recursivelyCheckParentsOfLeafNodesThatAreAllChecked(array) {
  for (const item of array) {
    // item is a parent
    if (item.children) {
      // all children of item are checked
      if (item.children.every(({ checked }) => !!checked)) {
        item.checked = true;
        recursivelyCheckParentsOfLeafNodesThatAreAllChecked(item.children);
      } else {
        console.log(`${item.name} has children that are unchecked.`);
        item.checked = false;
        // ~> here we need to now check the parents of item to false.
      }
    }
  }
  return array;
}

const uncheckedParentsWhereRelevant = recursivelyCheckParentsOfLeafNodesThatAreAllChecked(data);

console.log(uncheckedParentsWhereRelevant);

Answer

You need to recursively check the children and descendants.

const data = [
    {
        name: "College",
        checked: true,
        children: [
            { 
                name: "College of engineering",
                checked: true,
                children: [
                    {
                        name: "Computer Science",
                        checked: true,
                        children: [
                            {
                                name: "BSC Computer Science",
                                checked: false,
                            }
                        ]
                    }
                ]
            },
            { 
                name: "Humanties",
                checked: true,
                children: [
                    {
                        name: "Humans",
                        checked: true,
                        children: [
                            {
                                name: "HMS",
                                checked: true,
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

// If the bottom-most child segments are checked, also check the parent term
function check(obj) {
  if(obj.children){
     const uncheck = obj.children.reduce((acc,curr)=>acc||check(curr),false);
     if(uncheck) obj.checked = false;
  }
  return !obj.checked;
}

data.forEach(check);
console.log(data);