I got an object which looks like this :
{
"a": "string not empty",
"b": {
"c": "string not empty",
},
"d": {
"e": false,
"f": 0,
"g": true,
"h": 10
},
"i": {
"j": 0,
"k": null
},
"l": {
"m": null
},
"n": {
"o": 1,
"p": "string (not empty)",
"q": {}
},
"r": [],
"l": "2000-01-01T01:01:00.000Z",
}
Thanks to the code provided by here : https://stackoverflow.com/a/38364486/3912805 I can now remove all null
values of my nested object.
I used this function so far to removeNull
:
removeNull = (obj) => {
Object.keys(obj).forEach(key =>
(obj[key] && typeof obj[key] === 'object') && removeNull(obj[key]) ||
(obj[key] === undefined || obj[key] === null) && delete obj[key]
);
return obj;
};
But I would like to enhance this function to allow me to remove all empty arrays or any empty collection which may exists in my nested object.
Final results should be without k
, l
& m
, q
, r
, l
:
{
"a": "string not empty",
"b": {
"c": "string not empty",
},
"d": {
"e": false,
"f": 0,
"g": true,
"h": 10
},
"i": {
"j": 0
},
"n": {
"o": 1,
"p": "string (not empty)"
},
"l": "2000-01-01T01:01:00.000Z",
}
I need to keep all values which were set to 0
or to false
.
I would like to enhance this removeNull
's method using ES6 method, but so far I failed to do it.
I also tried old school method which was used for this How to deeply remove null values, empty objects and empty array from an object
itemToBool = item => {
if (typeof item !== 'object' || item === null) return item;
const cleanedItem = cleanObject(item);
return Object.keys(cleanedItem).length !== 0 && cleanedItem;
};
cleanObject = obj => {
if (Array.isArray(obj)) {
const newArr = obj.map(itemToBool).filter(Boolean);
return newArr.length && newArr;
}
const newObj = Object.entries(obj).reduce((a, [key, val]) => {
const newVal = itemToBool(val);
if (newVal !== null || newVal === false) a[key] = newVal;
return a;
}, {});
return Object.keys(newObj).length > 0 && newObj;
};
but it fails too.
You could take an straight forward approach by iterating the key/value pairs of the object and iterate nested iterable objects first and then delete the unwanted keys.
function clean(object) {
Object
.entries(object)
.forEach(([k, v]) => {
if (v && typeof v === 'object') {
clean(v);
}
if (v && typeof v === 'object' && !Object.keys(v).length || v === null || v === undefined) {
if (Array.isArray(object)) {
object.splice(k, 1);
} else {
delete object[k];
}
}
});
return object;
}
var object = { a: "string not empty", b: { c: "string not empty" }, d: { e: false, f: 0, g: true, h: 10 }, i: { j: 0, k: null }, l: { m: null }, n: { o: 1, p: "string (not empty)", q: {} }, r: [{ foo: null }] };
console.log(clean(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can exploit JSON.stringify
and it's optional second argument replacer
but be aware the following code removes null
and undefined
.
const sanitize = (obj) => {
return JSON.parse(JSON.stringify(obj, (key, value) => {
return (value === null ? undefined : value);
}));
};
const obj = {
"a": "string not empty",
"b": {
"c": "string not empty",
},
"d": {
"e": false,
"f": 0,
"g": true,
"h": 10
},
"i": {
"j": 0,
"k": null
},
"l": {
"m": null
},
"n": {
"o": 1,
"p": "string (not empty)",
"q": {}
},
"r": [],
"l": "2000-01-01T01:01:00.000Z",
}
console.log(sanitize(obj))
Thanks to Nina Scholz, my enhanced version will be :
cleanObject = function(object) {
Object
.entries(object)
.forEach(([k, v]) => {
if (v && typeof v === 'object')
cleanObject(v);
if (v &&
typeof v === 'object' &&
!Object.keys(v).length ||
v === null ||
v === undefined ||
v.length === 0
) {
if (Array.isArray(object))
object.splice(k, 1);
else if (!(v instanceof Date))
delete object[k];
}
});
return object;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With