首页 > 解决方案 > 根据子对象的“已检查”状态递归遍历对象数组

问题描述

我试图递归地取消选中所有有一个孩子的父对象checked: false 目前,我的函数正在为孩子的直接父母工作,checked: false即“BSC 计算机科学”checked: flase意味着“计算机科学”也变得如此checked: false

当一个项目被检查为假时,我如何再次遍历原始树。

预期产出


    [
        {
            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,
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]

谢谢

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);

标签: javascriptarraysrecursion

解决方案


一个简单的递归方法可能如下所示:

const allChecked = ({checked, children = []}) =>
  checked && children .every (allChecked)

const uncheckUp = (data) => data.map (({checked, children, ...rest}) => ({
  ...rest,
  checked: allChecked ({checked, children}),
  ...(children ? {children: uncheckUp (children)} : {})
}))

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}]}]}]}]


console .log (uncheckUp (data))
.as-console-wrapper {min-height: 100% !important; top: 0}

allChecked报告是否检查了一个节点及其所有后代。 uncheckUp( :-) ) 使用allChecked.

请注意,此版本将您的数据视为不可变的。结果是一个全新的对象。


推荐阅读