I'm looking to essentially "trim" a JSON object to only objects and properties that have meaningful non-empty data.
I need to write a performant function that takes an object like this:
[Function Input]
{
"id": "123",
"firstName": undefined
"lastName": null
"contactInfo": {
"email": "notreal@somedomain.com",
"contactInfo": {
"address": {
"streetAddress1": undefined,
"state": null
}
}
}
}
[Function Output]
{
"id": "123",
"contactInfo": {
"email": "notreal@somedomain.com"
}
}
This is what I've tried:
export function removeNullOrUndefinedProperties(obj: any): any {
return Object.entries(obj)
.filter(([_, v]) => v != null)
.reduce((acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeNullOrUndefinedProperties(v) : v }), {});
}
export function removeEmptyObjects(obj: any): any {
for (const k in obj) {
if (!obj[k] || typeof obj[k] !== 'object') {
continue; // If null or not an object, skip to the next iteration
}
// The property is an object
removeEmptyObjects(obj[k]); // <-- Make a recursive call on the nested object
if (Object.keys(obj[k]).length === 0) {
delete obj[k]; // The object had no properties, so delete that property
}
}
return obj;
}
Call to the function:
removeEmptyObjects(removeNullOrUndefinedProperties(json));
This solution is slow, and it doesn't always work; specifically, if you pass an array, it returns numbered indexes on the array which is unexpected data. How do I write this function in a correct and performant way?