根据条件从嵌套对象数组中删除项目

4
在我的应用中,从服务器返回的数据如下所示。它有非常深的嵌套:
var data = [{
    name: "root",
    children: [{
            name: "Parent1",
            children: [{
                    name: "Parent1-child1",
                    children: [{
                            name: "Parent1-child1-grandchild1",
                            children: [{
                                name: "Parent1-child1-grandchild1-last",
                                children:[]
                            }]
                        },
                        {
                            name: "Parent1-child1-grandchild2",
                            children: []
                        },
                        {
                            name: "Parent1-child1-grandchild3",
                            children: []
                        }
                    ]
                },
                {
                    name: "Paren1-child2",
                    children: [{
                            name: "Parent1-chil2-grandchild1",
                            children: []
                        },
                        {
                            name: "Parent1-child2-grandchild2",
                            children: [{
                                name: "Parent1-child2-grandchild2-last",
                                children: []
                            }]
                        },
                        {
                            name: "Parent1-child2-grandchild3",
                            children: []
                        }
                    ]
                },
                {
                    name: "Parent1-child3",
                    children: []
                }
            ]
        },
        {
            name: "Parent2",
            children: [{
                    name: "Parent2-child1",
                    children: []
                },
                {
                    name: "Parent2-child2",
                    children: [{
                            name: "Parent2-child2-grandchild1",
                            children: []
                        },
                        {
                            name: "Parent2-child2-grandchild2",
                            children: [{
                                name: "Parent2-child2-grandchild2-last",
                                children: []
                            }]
                        }
                    ]
                }
            ]
        },
        {
            name: "Parent3",
            children: []
        }
    ]
}];

要求循环遍历所有对象(包括深层嵌套的对象),如果子属性的值是空数组,则删除该对象。因此输出结果应该如下所示
var data = [{
    name: "root",
    children: [{
            name: "Parent1",
            children: [{
                    name: "Parent1-child1",
                    children: [{
                            name: "Parent1-child1-grandchild1",
                            children: []
                        },
                    ]
                },
                {
                    name: "Paren1-child2",
                    children: [
                        {
                            name: "Parent1-child2-grandchild2",
                            children: []
                        },
                    ]
                },
            ]
        },
        {
            name: "Parent2",
            children: [
                {
                    name: "Parent2-child2",
                    children: [
                        {
                            name: "Parent2-child2-grandchild2",
                            children: []
                        }
                    ]
                }
            ]
        }
    ]
}];

我尝试了以下代码,但它并没有按预期工作。请告诉我如何实现预期结果。
function checkChildrens(arr) {
    arr.forEach((ele,i) => {
    if(ele.hasOwnProperty('children')) {
        checkChildrens(ele['children']) 
    } else {
        arr.splice(i,1)
    }
    })
}
checkChildrens(data);

我也尝试使用过筛选方法,但是在那种情况下它并没有正常工作。

arr.filter((ele,i)=>{
   if(ele.hasOwnProperty('children') && ele.children.length !== 0 ){
      removeEmpty(ele.children)
   }else{
        return false;
    }
    return true;
})

你能展示一下这段代码的输出结果吗? - Krishanu
1
在这种情况下,数组过滤方法可能更适合您。 - robbieAreBest
你离解决方案太近了,只需要检查长度就可以:if (ele.hasOwnProperty('children') && ele.children.length !== 0) - Eldar
2个回答

5
您可以通过检查子数组长度来重建新对象。

function filter(array) {
    return array.reduce((r, o) => {
        if (o.children && o.children.length) {
            r.push(Object.assign({}, o, { children: filter(o.children) }));
        }
        return r;
    }, []);
}

var data = [{ name: "root", children: [{ name: "Parent1", children: [{ name: "Parent1-child1", children: [{ name: "Parent1-child1-grandchild1", children: [{ name: "Parent1-child1-grandchild1-last", children: [] }] }, { name: "Parent1-child1-grandchild2", children: [] }, { name: "Parent1-child1-grandchild3", children: [] }] }, { name: "Paren1-child2", children: [{ name: "Parent1-chil2-grandchild1", children: [] }, { name: "Parent1-child2-grandchild2", children: [{ name: "Parent1-child2-grandchild2-last", children: [] }] }, { name: "Parent1-child2-grandchild3", children: [] }] }, { name: "Parent1-child3", children: [] }] }, { name: "Parent2", children: [{ name: "Parent2-child1", children: [] }, { name: "Parent2-child2", children: [{ name: "Parent2-child2-grandchild1", children: [] }, { name: "Parent2-child2-grandchild2", children: [{ name: "Parent2-child2-grandchild2-last", children: [] }] }] }] }, { name: "Parent3", children: [] }] }],
    result = filter(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

删除所有嵌套的空子元素的方法(除了最后一个。这个对象为空,但没有子元素属性)。

function filter(array) {
    return array.reduce((r, o) => {
        if (o.children) {
            var children = filter(o.children);
            if (children.length) r.push(Object.assign({}, o, { children }));
        } else {
            r.push(o);
        }
        return r;
    }, []);
}

var data = [{ name: "root", children: [{ name: "Parent1", children: [{ name: "Parent1-child1", children: [{ name: "Parent1-child1-grandchild1", children: [{ name: "Parent1-child1-grandchild1-last", children: [] }] }, { name: "Parent1-child1-grandchild2", children: [] }, { name: "Parent1-child1-grandchild3", children: [] }] }, { name: "Paren1-child2", children: [{ name: "Parent1-chil2-grandchild1", children: [] }, { name: "Parent1-child2-grandchild2", children: [{ name: "Parent1-child2-grandchild2-last", children: [] }] }, { name: "Parent1-child2-grandchild3", children: [] }] }, { name: "Parent1-child3", children: [] }] }, { name: "Parent2", children: [{ name: "Parent2-child1", children: [] }, { name: "Parent2-child2", children: [{ name: "Parent2-child2-grandchild1", children: [] }, { name: "Parent2-child2-grandchild2", children: [{ name: "Parent2-child2-grandchild2-last", children: [] }] }] }] }, { name: "Parent3", children: [{}] }] }],
    result = filter(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


我认为问题出在当您删除项目时,还会创建空子项,代码应该再次运行,直到没有剩余的空子项。 - Eldar
1
@Eldar,抱歉,操作员希望得到空数组,正如上面所述。 - Nina Scholz
是的,我注意到这点花了我很长时间 :) - Eldar
@NinaScholz但是这个解决方案对于新手来说很难理解。你为新开发人员介绍了reduce, assign,但他们并没有正确理解递归。 - Medet Tleukabiluly
@NinaScholz,非常感谢。正如Eldar所说,如果代码应该一直运行直到没有空的子项剩余,那么如何重写上面的代码? - yasarui
显示剩余4条评论

1

var data = [{
  name: "root",
  children: [{
      name: "Parent1",
      children: [{
          name: "Parent1-child1",
          children: [{
              name: "Parent1-child1-grandchild1",
              children: [{
                name: "Parent1-child1-grandchild1-last",
                children: []
              }]
            },
            {
              name: "Parent1-child1-grandchild2",
              children: []
            },
            {
              name: "Parent1-child1-grandchild3",
              children: []
            }
          ]
        },
        {
          name: "Paren1-child2",
          children: [{
              name: "Parent1-chil2-grandchild1",
              children: []
            },
            {
              name: "Parent1-child2-grandchild2",
              children: [{
                name: "Parent1-child2-grandchild2-last",
                children: []
              }]
            },
            {
              name: "Parent1-child2-grandchild3",
              children: []
            }
          ]
        },
        {
          name: "Parent1-child3",
          children: []
        }
      ]
    },
    {
      name: "Parent2",
      children: [{
          name: "Parent2-child1",
          children: []
        },
        {
          name: "Parent2-child2",
          children: [{
              name: "Parent2-child2-grandchild1",
              children: []
            },
            {
              name: "Parent2-child2-grandchild2",
              children: [{
                name: "Parent2-child2-grandchild2-last",
                children: []
              }]
            }
          ]
        }
      ]
    },
    {
      name: "Parent3",
      children: []
    }
  ]
}];

function checkChildrens(arr) {
  let res = []

  arr.forEach(v => {
    if (v.children && v.children.length) {
      res = res.concat({
        name: v.name,
        children: checkChildrens(v.children)
      })
    }
  })

  return res
}
console.log(checkChildrens(data));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接