0

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?

Kellen Stuart
  • 6,353
  • 5
  • 50
  • 73

0 Answers0