Home > Mobile >  How to remove object (element) based on property from nested obj
How to remove object (element) based on property from nested obj

Time:11-20

How to remove an object (element) based on the property from nested obj. For example, I need to remove all objects with type: 'green' from obj tree if obj has children it will be also removed.

const obj = {
  id: '01',
  children: [
    {
      id: '02',
      type: 'green',
      children: [
        {
          id: '03',
          type: 'black',
          children: [],
        },
        {
          id: '04',
          type: 'green',
          children: [
            {
              id: '05',
              type: 'white',
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '06',
      type: 'black',
      children: [
        {
          id: '07',
          type: 'green',
          children: [],
        },
        {
          id: '08',
          type: 'white',
          children: [
            {
              id: '09',
              type: 'green',
              children: [],
            }
          ],
        }
      ],
    },
  ]
}

// expected result (if remove type: "green")

const expectedObj = {
  id: '01',
  type: 'orange',
  children: [
    {
      id: '06',
      type: 'black',
      children: [
        {
          id: '08',
          type: 'white',
          children: [],
        }
      ],
    },
  ]
}

What I am trying to do

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

let data = obj.children
console.dir(removeByType(data, 'black'), { depth: null })

but { id: '03', type: 'black', children: [] } is still in the object tree

CodePudding user response:

You were close, just missing that each instance was an array that you had to map through

const removeByType = (data, type) => {
  data = data.filter(d => d.type !== type)
  data = data.map(d => {
    d.children = removeByType(d.children, type);
    return d;
  })
  return data
}

const obj = {
  id: '01',
  children: [{
      id: '02',
      type: 'green',
      children: [{
          id: '03',
          type: 'black',
          children: [],
        },
        {
          id: '04',
          type: 'green',
          children: [{
            id: '05',
            type: 'white',
            children: [],
          }],
        }
      ],
    },
    {
      id: '06',
      type: 'black',
      children: [{
          id: '07',
          type: 'green',
          children: [],
        },
        {
          id: '08',
          type: 'white',
          children: [{
            id: '09',
            type: 'green',
            children: [],
          }],
        }
      ],
    },
  ]
}


const removeByType = (data, type) => {
  data = data.filter(d => d.type !== type)
  data = data.map(d => {
    d.children = removeByType(d.children, type);
    return d;
  })
  return data
}

console.dir(removeByType(obj.children, 'black'), {
  depth: null
})

CodePudding user response:

I've done that..

const removeByType = (data, type) =>
  {
  for (let i=data.children.length;--i>=0;)
    {
    if ( data.children[i].type===type)  data.children.splice(i,1)
    else                    removeByType (data.children[i], type)
    }
  return data // just for chaining ... ?
  }

usage:

const my_obj = 
  { id: '01',             type: 'orange', children:       //   stay
    [ { id: '02',         type: 'green',  children:          // - green
        [ { id: '03',     type: 'black',  children: [] }     // -
        , { id: '04',     type: 'green',  children:          // -
            [ { id: '05', type: 'white',  children: [] }     // -
            ] 
      } ] } 
    , { id: '06',         type: 'black',  children:       //   stay
        [ { id: '07',     type: 'green',  children: [] }     // - green
        , { id: '08',     type: 'white',  children:       //   stay
            [ { id: '09', type: 'green',  children: [] }     // - green
            ] 
  } ] } ] } 

const removeByType = (data, type) =>
  {
  for (let i=data.children.length;--i>=0;)
    {
    if ( data.children[i].type===type)  data.children.splice(i,1)
    else                    removeByType (data.children[i], type)
    }
  return data
  }

console.log( removeByType(my_obj, 'green') )
 // my_obj is now updated...
console.log( my_obj )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

  • Related