Skip to content

Instantly share code, notes, and snippets.

@Mazuh
Last active September 22, 2022 07:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Mazuh/8209a608a655f91b9de319872d7a660a to your computer and use it in GitHub Desktop.
Save Mazuh/8209a608a655f91b9de319872d7a660a to your computer and use it in GitHub Desktop.
Remove all empty objects and undefined values from a nested object -- an enhanced and vanilla version of Lodash's `compact`.
function compactObject(data) {
if (typeof data !== 'object') {
return data;
}
return Object.keys(data).reduce(function(accumulator, key) {
const isObject = typeof data[key] === 'object';
const value = isObject ? compactObject(data[key]) : data[key];
const isEmptyObject = isObject && !Object.keys(value).length;
if (value === undefined || isEmptyObject) {
return accumulator;
}
return Object.assign(accumulator, {[key]: value});
}, {});
}
@Mazuh
Copy link
Author

Mazuh commented Jan 14, 2019

E.g. of application:

compactObject({
  width: {
    min: undefined,
    max: undefined,
  },
  height: {
    min: undefined,
    max: undefined,
  },
}); // returns { }

It's pure, so no side effects on arguments provided.

@JeremiAnastaziak
Copy link

JeremiAnastaziak commented May 24, 2021

line 7 fails when checking for arrays, example below

['test'] => { 0: 'test' }

@sanjarbarakayev
Copy link

sanjarbarakayev commented Jun 3, 2022

this function changes type array to object:

['a', 'b'] => {0: 'a', 1: 'b'}

@salmanfazal01
Copy link

salmanfazal01 commented Aug 11, 2022

this function changes type array to object:

['a', 'b'] => {0: 'a', 1: 'b'}

Inside the reduce, change the value variable from const to let then add another if statement

if (typeof data !== "object") {
    return data;
  }

  return Object.keys(data).reduce(function (accumulator, key) {
    const isObject = data[key] !== null && typeof data[key] === "object";
    let value = isObject ? compactObject(data[key]) : data[key];
    const isEmptyObject = isObject && !Object.keys(value).length;
    if (value === undefined) {  // || isEmptyObject
      return accumulator;
    }
    if (Array.isArray(data[key])) {
      value = Object.values(value);
    }

    return Object.assign(accumulator, { [key]: value });
  }, {});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment