Ruslan Neck
Ruslan Neck

Reputation: 59

How to remove undefined properties from object and elements from array

I have a following object:

{
  a: {
    b: {
      c: undefined
    }
  },
  b: {
    c: 15,
    d: []
  },
  c: {
    d: [11, undefined ,12],
    e: {}
  }
}

And i need to get this:

{
 b: {
  c: 15
 },
 c: {
  d: [11, 12]
 }
}

I found this function (source: Remove undefined properties from object )

function filter(obj) {
  for (var key in obj) {
    if (obj[key] === undefined) {
      delete obj[key];
      continue;
    }
    if (obj[key] && typeof obj[key] === "object") {
      filter(obj[key]);
      if (!Object.keys(obj[key]).length) {
        delete obj[key];
      }
    }
  }
  return obj;
}

But it just delete elements of array and it turns out the following

{
 b: {
  c: 15
 },
 c: {
  d: [11, empty ,12]
 }
}

Upvotes: 0

Views: 227

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370819

You need a recursive solution. Make a function that takes a value and returns something falsey if its value is falsey, or if all of its recursive elements are falsey or empty arrays or without keys:

const removeRecursive = (obj) => {
  // Falsey primitive, including null:
  if (!obj) return;
  // Truthy primitive (or function):
  if (typeof obj !== 'object') return obj;
  // Array, transform all values and return the new array
  // if there are any truthy transformed values:
  if (Array.isArray(obj)) {
    const newArr = obj.map(removeRecursive).filter(Boolean);
    return newArr.length ? newArr : undefined;
  }
  // Otherwise, it's an object:
  const newObj = Object.fromEntries(
    Object.entries(obj)
      .map(([key, val]) => ([key, removeRecursive(val)]))
      .filter(([, val]) => val)
  );
  if (Object.keys(newObj).length) {
    return newObj;
  }
};

const obj = {
  a: {
    b: {
      c: undefined
    }
  },
  b: {
    c: 15,
    d: []
  },
  c: {
    d: [11, undefined ,12],
    e: {}
  }
};

console.log(removeRecursive(obj));

Upvotes: 1

Related Questions