0

How do I remove an element from a JavaScript object by ID? For instance I have to remove 004 or 007:

const obj = {
  id: '001',
  children: [
    {
      id: '002',
      children: [
        {
          id: '003',
          children: [],
        },
        {
          id: '004',
          children: [
            {
              id: '005',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '006',
      children: [
        {
          id: '007',
          children: [],
        }
      ],
    },
  ]
}

i am trying to like this, find id but what should be next. It is expected to remove id from the object.

const removeById = (obj = {}, id = '') => {
  console.log('obj: ', obj)

  const search = obj.children.find(o => o.id === id)
  console.log('##search: ', search)
  if(search) {
    console.log('## parent id: ', obj.id)
    ...
  }
  if (obj.children && obj.children.length > 0) {
    obj.children.forEach(el => removeById(el, id));
  }
}

removeById(obj, '007')
3
  • If you remove 004,the sub element will also remove? Commented Nov 18, 2022 at 2:39
  • @lucumt yes, sub also should be deleted Commented Nov 18, 2022 at 3:03
  • Is the ID unique? if it's not unique,then we need to traverse all the objects Commented Nov 18, 2022 at 3:05

2 Answers 2

1

You can use findIndex to get the location in the array. To remove an element from an array you need to use splice.

You can then loop over the children with some and check the children's children. Using some, you can exit out when you find the id so you do not have to keep looping.

let obj = {
  id: '001',
  children: [
    {
      id: '002',
      children: [
        {
          id: '003',
          children: [],
        },
        {
          id: '004',
          children: [
            {
              id: '005',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '006',
      children: [
        {
          id: '007',
          children: [],
        }
      ],
    },
  ]
}

const removeById = (parentData, removeId) => {

   // This is only the parent level!
   // If you will never delete the first level parent, this is not needed
   if (parentData.id === removeId){
     Object.keys(data).forEach(key => delete parentData[key]);
     return true;
   }
   
   function recursiveFind (children) {
     // check if any of the children have the id
     const index = children.findIndex(({id}) => id === removeId);
 
     // if we have an index
     if (index != -1) {
       // remove it
       children.splice(index, 1);
       // say we found it
       return true;
     }
   
     // Loop over the chldren check their children
     return children.some(child => recursiveFind(child.children));
   }

   return recursiveFind(parentData.children);
}


removeById(obj,'004');
removeById(obj,'007');
console.log(obj)

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

Comments

1

We can use a recursive function to do it

let obj = {
  id: '001',
  children: [
    {
      id: '002',
      children: [
        {
          id: '003',
          children: [],
        },
        {
          id: '004',
          children: [
            {
              id: '005',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '006',
      children: [
        {
          id: '007',
          children: [],
        }
      ],
    },
  ]
}

const removeById = (data,id) =>{
  if(data.id === id){
    delete data.id
    delete data.children
    return
   }
   data.children.forEach(d =>{
     removeById(d,id)
   })
}

removeById(obj,'006')
console.log(obj)


Update: not leave an empty object after removing

let obj = {
  id: '001',
  children: [
    {
      id: '002',
      children: [
        {
          id: '003',
          children: [],
        },
        {
          id: '004',
          children: [
            {
              id: '005',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '006',
      children: [
        {
          id: '007',
          children: [],
        }
      ],
    },
  ]
}

let match = false
const removeById = (data,id) =>{
  match = data.some(d => d.id == id)
  if(match){
      data = data.filter(d => d.id !== id)
   }else{
     data.forEach(d =>{
       d.children = removeById(d.children,id)
     })
   }
   return data
}

let data = [obj]
console.log(removeById(data,'004'))

4 Comments

If the id does not repeat, this does a lot of extra looping.
@epascarello Then we can use a global variable to let it continue loop or not,but I do not find a way how to remove {},do you have any ideas?
You are also leaving an empty object
@epascarello Yes,that's what I just ask advice from you,in order to not leven an empty {} maybe I need to use filter to do it

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.