Home > Mobile >  How to remove empty arrays in a nested array/object?
How to remove empty arrays in a nested array/object?

Time:07-20

I have an array of objects that have array within themselves. I want to loop through the object and delete any empty arrays that I have. The object is shown below:

let a=[{children:[{children:[1,2]},{children:[5,6]}]},
       {children:[{children:[]},{children:[5,6]}]},
       {children:[{children:[]},{children:[]}]},
       {children:[]}]

I am trying to achieve the desired result by applying the code below but I am getting an error saying cannot read property 'children' of undefined.

  function removeEmpty(array){
        for(var i=array.length-1;i>=0;i--){
            if(array[i].children){
                if(array[i].children.length){
                    for(var j=array[i].children.length-1;j=>0;j--){
                        if(array[i].children[j].children){
                            removeEmpty(array[i].children[j])
                        }else{
                            array[i].splice[j,1]
                        }
                    }
                    
                    if(!array[i].children.length){
                        array.splice(i,1)
                    }
                }else{
                    array.splice(i,1)
                }
            }
        }
    }
    
    removeEmpty(a)

Expected outcome:

  expected outcome =[{children:[{children:[1,2]},{children:[5,6]}]},
     {children:[{children:[5,6]}]}]

If there are adjustments I can make to the existing code or use a different approach please let me know. Thank you.

CodePudding user response:

To achieve your goal you can use the .reduce() method.

const a = [{
    children: [{
      children: [1, 2]
    }, {
      children: [5, 6]
    }]
  },
  {
    children: [{
      children: []
    }, {
      children: [5, 6]
    }]
  },
  {
    children: [{
      children: []
    }, {
      children: []
    }]
  },
  {
    children: []
  }
]

const b = a.reduce((previousValue, currentValue) => {
  const data = []
  if (currentValue.children.length > 0) {
    currentValue.children.forEach((e) => {
      if (e.children.length > 0) data.push(e);
    });
  }
  if (data.length > 0) previousValue.push({children: data});
  return previousValue;
}, []);

console.log(b);

CodePudding user response:

Here is a prune function that reduces a node with children. Just make sure you wrap incoming data in a node with children.

For each of the nodes children, you filter the children based on the child count.

const data = [
  { children: [{ children: [1,2] }, { children: [5,6] }] },
  { children: [{ children: [] }, { children: [5,6] }] },
  { children: [{ children: [] }, { children: [] }] },
  { children: [] },
];

const prune = (node, key = 'children') =>
  node[key].reduce((prev, curr) =>
    (children => children.length
        ? { [key]: [...prev[key], { [key]: children }] }
        : prev)
      (curr[key].filter(child => child[key].length)),
    { [key]: [] });

const tree = prune({ children: data });

tree.children.forEach(child => console.log(JSON.stringify(child)));
.as-console-wrapper { top: 0; max-height: 100% !important; }
.as-console-row-code { font-size: smaller !important; }

  • Related