yasarui
yasarui

Reputation: 6563

Remove items from nested array of objects based on a condition

In my application, I have data returned from the server like below. It has very deep nesting:

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: []
        }
    ]
}];

The requirement is to loop through all the objects (deep nested level also) and remove the object if the children property has a value of an empty array. So the output should be like below

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: []
                        }
                    ]
                }
            ]
        }
    ]
}];

I have tried the following code, but it doesn't work as expected. Please let me know how to achieve the expected result.

function checkChildrens(arr) {
    arr.forEach((ele,i) => {
    if(ele.hasOwnProperty('children')) {
        checkChildrens(ele['children']) 
    } else {
        arr.splice(i,1)
    }
    })
}
checkChildrens(data);

I have tried with the filter method also in that case. It is not working correctly.

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

Upvotes: 4

Views: 975

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386560

You could rebuild new objects by checking the children array length.

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

Approach for removing all nested empty children (except the last one. This has an empty object, but no children property).

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

Upvotes: 5

Medet Tleukabiluly
Medet Tleukabiluly

Reputation: 11930

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

Upvotes: 1

Related Questions