'How to remove a property from nested javascript objects any level deep?

Let's say I have nested objects, like:

var obj = {
    "items":[
        {
            "name":"Item 1", 
            "value": "500",
            "options": [{...},{...}]
        },
        {
            "name":"Item 2", 
            "value": "300",
            "options": [{...},{...}]
        }
    ],
    "name": "Category",
    "options": [{...},{...}]
};

I want to remove the options property from any level deep from all the objects. Objects can be nested within objects, and arrays as well.

We're currently using Lodash in the project, but I'm curious about any solutions.



Solution 1:[1]

There is no straight forward way to achieve this, however you can use this below function to remove a key from JSON.

function filterObject(obj, key) {
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            filterObject(obj[i], key);
        } else if (i == key) {
            delete obj[key];
        }
    }
    return obj;
}

and use it like

var newObject = filterObject(old_json, "option");

Solution 2:[2]

Modifying the above solution, To delete "dataID" which appears multiple times in my JSON . mentioned below code works fine.

var candidate = {
  "__dataID__": "Y2FuZGlkYXRlOjkuOTI3NDE5MDExMDU0Mjc2",
  "identity": {
    "__dataID__": "aWRlbnRpdHk6NjRmcDR2cnhneGE3NGNoZA==",
    "name": "Sumanth Suvarnas"
  },  
};

candidate = removeProp(candidate, "__dataID__")

console.log(JSON.stringify(candidate, undefined, 2));

function removeProp(obj, propToDelete) {
   for (var property in obj) {
      if (typeof obj[property] == "object") {
         delete obj.property
         let newJsonData= this.removeProp(obj[property], propToDelete);
         obj[property]= newJsonData
      } else {
          if (property === propToDelete) {
            delete obj[property];
          }
        }
    }
    return obj
}

Solution 3:[3]

We now use object-scan for data processing tasks like this. It's very powerful once you wrap your head around it. Here is how you'd answer your questions

// const objectScan = require('object-scan');

const prune = (input) => objectScan(['**.options'], {
  rtn: 'count',
  filterFn: ({ parent, property }) => {
    delete parent[property];
  }
})(input);

const obj = { items: [{ name: 'Item 1', value: '500', options: [{}, {}] }, { name: 'Item 2', value: '300', options: [{}, {}] }], name: 'Category', options: [{}, {}] };

console.log(prune(obj));
// => 3

console.log(obj);
// => { items: [ { name: 'Item 1', value: '500' }, { name: 'Item 2', value: '300' } ], name: 'Category' }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Solution 4:[4]

A little modification of void's answer that allows for deletion of propertise which are also objects

function filterObject(obj, key) {
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (i == key) {
            delete obj[key];
        } else if (typeof obj[i] == 'object') {
            filterObject(obj[i], key);
        }
    }
    return obj;
}

Solution 5:[5]

I had a similar issue and I got it resolved. I hope my solution might be helpful to someone.

I use Es6 ... spread operator to do a shallow copy of an object and made null to property I was not interested.

const newObject = {
   ...obj.items,
   ...obj.name,
   options: null // option property will be null.
}

Solution 6:[6]

function omit(source) {
  return isArray(source)
    ? source.map(omit)
    : isObject(source)
    ? (({ options, ...rst }) => mapValues(rst, omit))(source)
    : source;
}

as with lodash, that's an easy thing, also you can specify the key via an param like this

function omit(source, omitKey) {
  return isArray(source)
    ? source.map(partialRight(omit,omitKey)))
    : isObject(source)
    ? (({[omitKey]: _, ...rst }) => mapValues(rst, partialRight(omit,omitKey)))(source)
    : source;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marco Bonelli
Solution 2 Muhammed Moussa
Solution 3
Solution 4 sboyd
Solution 5 Niyongabo Eric
Solution 6