Reputation: 59
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
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