'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 |
