2

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.

4
  • Do you mean also to remove empty objects, not just arrays? Commented Jul 19, 2022 at 18:30
  • You're facing this issue because you're decreasing the size of the array (splicing) while looping it from the end. As you remove an element, the size of the array decreases and the index used is out of bounds. Commented Jul 19, 2022 at 18:52
  • Kind of related to stackoverflow.com/questions/42736031/… Commented Jul 19, 2022 at 18:59
  • Yeh I mean to delete the empty objects too. And I am splicing from the end so that shouldn’t cause any issue? Commented Jul 19, 2022 at 19:18

3 Answers 3

0

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

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

var updatedArray = children.filter(item => item.children.length > 0)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.