Javascript 递归删除';家长';基于子对象的属性';s状态

Javascript 递归删除';家长';基于子对象的属性';s状态,javascript,json,recursion,javascript-objects,Javascript,Json,Recursion,Javascript Objects,我有一个access JSON对象,如下所示 { "data": [ { "label": "Self Service", "data": { "roles": [ "Employee", "Manager", "System Admin

我有一个access JSON对象,如下所示

{
  "data": [
    {
      "label": "Self Service",
      "data": {
        "roles": [
          "Employee",
          "Manager",
          "System Administrator"
        ]
      },
      "children": [
        {
          "label": "Attendance",
          "icon": "pi pi-file",
          "data": {
            "roles": [
              "Employee",
              "System Administrator"
            ]
          },
          "children": [
            {
              "label": "Clocking",
              "icon": "pi pi-file",
              "data": {
                "roles": [
                  "Employee",
                  "System Administrator"
                ],
                "routerLink": ["ESS-ATT-clocking"]
              }
            },
            {
              "label": "History",
              "icon": "pi pi-file",
              "data": {
                "roles": [
                  "Employee",
                  "System Administrator"
                ]
              }
            }
          ]
        },
        {
          "label": "Claim",
          "icon": "pi pi-file",
          "data": {
            "roles": [
              "Manager",
              "System Administrator"
            ]
          },
          "children": [
            {
              "label": "Entitlement & Request",
              "icon": "pi pi-file",
              "data": {
                "roles": [
                  "Manager",
                  "System Administrator"
                ]
              }
            }
          ]
        }
      ]
    },
  ]
}
存储在变量accessCtrl中。我还有一个变量

role = "Employee"
每个子节点都与“children”属性连接。 如果data.role数组中不存在“role”,如何循环(递归)删除整个JSON对象“accessCtrl”并删除特定节点

e、 g

对象应该返回

{
  "data": [
    {
      "label": "Self Service",
      "data": {
        "roles": [
          "Employee",
          "Manager",
          "System Administrator"
        ]
      },
      "children": [
        {
          "label": "Claim",
          "icon": "pi pi-file",
          "data": {
            "roles": [
              "Manager",
              "System Administrator"
            ]
          },
          "children": [
            {
              "label": "Entitlement & Request",
              "icon": "pi pi-file",
              "data": {
                "roles": [
                  "Manager",
                  "System Administrator"
                ]
              }
            }
          ]
        }
      ]
    },
  ]
}
这是我当前的代码,它似乎不能正常工作

function removeNode(obj, parent) {
  for (let prop in obj) {
    if (
      prop === "data" &&
      prop.hasOwnProperty("roles") &&
      !prop.roles.includes(this.role)
    ) {
      if (parent) {
        delete parent.children;
      }
    } else if (typeof obj[prop] === "object") removeNode(obj[prop], obj);
  }
}

removeNode(this.accessCtrl, null);
console.log("this.accessCtrl=", this.accessCtrl);

要使函数递归,它需要调用自身。 请让我知道,如果你需要更多的解释如何工作

const输入={
“数据”:[{
“标签”:“自助服务”,
“数据”:{
“角色”:[
“雇员”,
“经理”,
“系统管理员”
]
},
“儿童”:[{
“标签”:“出席人数”,
“图标”:“pi文件”,
“数据”:{
“角色”:[
“雇员”,
“系统管理员”
]
},
“儿童”:[{
“标签”:“计时”,
“图标”:“pi文件”,
“数据”:{
“角色”:[
“雇员”,
“系统管理员”
],
“路由链接”:[“ESS ATT时钟”]
}
},
{
“标签”:“历史记录”,
“图标”:“pi文件”,
“数据”:{
“角色”:[
“雇员”,
“系统管理员”
]
}
}
]
},
{
“标签”:“索赔”,
“图标”:“pi文件”,
“数据”:{
“角色”:[
“经理”,
“系统管理员”
]
},
“儿童”:[{
“标签”:“权利和请求”,
“图标”:“pi文件”,
“数据”:{
“角色”:[
“经理”,
“系统管理员”
]
}
}]
}
]
}]
}
const role=“经理”;
常量=(树,角色)=>{
常数newTree=[]
用于(树的常量项){
if(item.data.roles.includes(role)){
if(项目.子项){
item.children=removoles(item.children,role)//这是它递归的地方
}
newTree.push(项目)
}
}
返回新树;
}
const result={data:removoles(input.data,role)}

控制台日志(结果)我将把过滤递归数组的代码从测试业务需求的实际代码中分离出来(这里是
({data:{roles}})=>roles.includes('Manager')
),这里有一种可能性:

constfilterdeep=(pred)=>(xs)=>
xs.flatMap(x=>pred(x)
?[{…x,children:filterDeep(pred)(x.children | |[])]
: []
)
常量justManagers=({data,…rest})=>({
休息
数据:filterDeep(({data:{roles}})=>roles.includes('Manager'))(数据)
}))
const input={data:[{label:“自助服务”,data:{roles:[“员工”,“经理”,“系统管理员”]},children:[{label:“考勤”,icon:“pi文件”,data:{roles:[“员工”,“系统管理员”]},children:[{label:“计时”,icon:“pi文件”,data:{roles:[“员工”,“系统管理员”],routerLink:[“ESS ATT计时”]}},{标签:“历史”,图标:“权限和请求”,数据:{角色:[“员工”,“系统管理员”]}}}},{标签:“声明”,图标:“权限文件”,数据:{角色:[“经理”,“系统管理员”]},子项:[{标签:“权限和请求”,图标:“权限和请求”,数据:{角色:[“经理”,“系统管理员”]}}}}}
控制台日志(
管理人员(输入)
)
.as控制台包装{max height:100%!important;top:0}
这里是一个使用的解决方案。我们使用对象扫描进行数据处理,但这确实需要一点时间才能让您的头脑清醒过来。从概念上讲,解决方案很简单:我们先检查“叶子”,然后在(1)不存在子项和(2)不存在所需角色的情况下升级层次结构并删除

//const objectScan=require('object-scan');
const input={data:[{label:'Self Service',data:{roles:['Employee','Manager','System Administrator']},children:[{label:'attention',icon:'pi-pi-file',children:[{label:'Employee','System Administrator']},data:{roles:['Employee:['Employee','System Administrator']],routerLink['ESS-ATT-clocking']},{label:'History',icon:'pi-pi-pi-file',data:{roles:['Employee','System Administrator']}},{label:['Employee','System Administrator']},{label:'entity&Request',icon:'pi-pi-pi-file',data:{roles:['Manager','System Administrator']}}}}}}};
const prune=(角色,数据)=>objectScan(['{data,**.children}[*]']{
rtn:'计数',
filterFn:({value,property,parent})=>{
如果(
!value.data.roles.includes(角色)
&&(value.children | |[])。长度===0
) {
父。拼接(属性,1);
返回true;
}
返回false;
}
})(数据);
log(prune('Manager',input));//返回删除次数
// => 3
控制台日志(输入);
/*=>{数据:[
{
标签:“自助服务”,
数据:{角色:[“员工”、“经理”、“系统管理员”]},
儿童:[
{标签:'Claim',图标:'pi file',数据:{角色:['Manager','System Administrator']},子级:[
{标签:“授权和请求”,图标:“pi文件”,数据:{角色:[“经理”,“系统管理员”]}
] }
]
}
]}*/
。作为控制台包装{最大高度:100%!重要;顶部:0}

我无法判断代码的效率(因为这对于中级程序员来说太难了)。@Scott你是忍者!但我决定作为第一个解决方案,因为我可能很难维护你的代码。它对我来说太高级了:)
function removeNode(obj, parent) {
  for (let prop in obj) {
    if (
      prop === "data" &&
      prop.hasOwnProperty("roles") &&
      !prop.roles.includes(this.role)
    ) {
      if (parent) {
        delete parent.children;
      }
    } else if (typeof obj[prop] === "object") removeNode(obj[prop], obj);
  }
}

removeNode(this.accessCtrl, null);
console.log("this.accessCtrl=", this.accessCtrl);