如何删除JavaScript对象中未定义或空的所有属性?
(这个问题与数组的问题类似)
如何删除JavaScript对象中未定义或空的所有属性?
(这个问题与数组的问题类似)
当前回答
清除空数组、空对象、空字符串、未定义、NaN和空值。
function objCleanUp(obj:any) {
for (var attrKey in obj) {
var attrValue = obj[attrKey];
if (attrValue === null || attrValue === undefined || attrValue === "" || attrValue !== attrValue) {
delete obj[attrKey];
} else if (Object.prototype.toString.call(attrValue) === "[object Object]") {
objCleanUp(attrValue);
if(Object.keys(attrValue).length===0)delete obj[attrKey];
} else if (Array.isArray(attrValue)) {
attrValue.forEach(function (v,index) {
objCleanUp(v);
if(Object.keys(v).length===0)attrValue.splice(index,1);
});
if(attrValue.length===0)delete obj[attrKey];
}
}
}
objCleanUp(myObject)
(attrValue !== attrValue)检查NaN。在这里学的
其他回答
如果您更喜欢纯/函数方法
const stripUndef = obj =>
Object.keys(obj)
.reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
更短的ES6纯解决方案,将其转换为数组,使用过滤器函数并将其转换回对象。 也很容易创建一个函数。
顺便说一句。使用这个.length > 0我检查是否有一个空字符串/数组,因此它将删除空键。
const MY_OBJECT = { f: 'te', a: [] }
Object.keys(MY_OBJECT)
.filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
.reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});
JS BIN https://jsbin.com/kugoyinora/edit?js,console
除了删除属性,还可以使用非空键创建一个新对象。
const removeEmpty = (obj) => {
return Object.keys(obj).filter(key => obj[key]).reduce(
(newObj, key) => {
newObj[key] = obj[key]
return newObj
}, {}
)
}
ES10 - ES2019和
一个简单的一行程序(返回一个新对象)。
let o = Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
和上面一样,只是写成函数形式。
function removeEmpty(obj) {
return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));
}
此函数使用递归从嵌套对象中删除项。
function removeEmpty(obj) {
return Object.fromEntries(
Object.entries(obj)
.filter(([_, v]) => v != null)
.map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v])
);
}
ES6 / ES2015和
简单的一行代码。警告:这将改变给定的对象,而不是返回一个新的对象。
Object.keys(obj).forEach((k) => obj[k] == null && delete obj[k]);
单个声明(不改变给定对象)。
let o = Object.keys(obj)
.filter((k) => obj[k] != null)
.reduce((a, k) => ({ ...a, [k]: obj[k] }), {});
和上面一样,只是写成函数形式。
function removeEmpty(obj) {
return Object.entries(obj)
.filter(([_, v]) => v != null)
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
}
此函数使用递归从嵌套对象中删除项。
function removeEmpty(obj) {
return Object.entries(obj)
.filter(([_, v]) => v != null)
.reduce(
(acc, [k, v]) => ({ ...acc, [k]: v === Object(v) ? removeEmpty(v) : v }),
{}
);
}
与上面的函数相同,但以命令式(非函数式)风格编写。
function removeEmpty(obj) {
const newObj = {};
Object.entries(obj).forEach(([k, v]) => {
if (v === Object(v)) {
newObj[k] = removeEmpty(v);
} else if (v != null) {
newObj[k] = obj[k];
}
});
return newObj;
}
ES5 / ES2009例子
在过去,事情要啰嗦得多。
这是一个以函数式风格编写的非递归版本。
function removeEmpty(obj) {
return Object.keys(obj)
.filter(function (k) {
return obj[k] != null;
})
.reduce(function (acc, k) {
acc[k] = obj[k];
return acc;
}, {});
}
这是一个以命令式风格编写的非递归版本。
function removeEmpty(obj) {
const newObj = {};
Object.keys(obj).forEach(function (k) {
if (obj[k] && typeof obj[k] === "object") {
newObj[k] = removeEmpty(obj[k]);
} else if (obj[k] != null) {
newObj[k] = obj[k];
}
});
return newObj;
}
还有一个函数式的递归版本。
function removeEmpty(obj) {
return Object.keys(obj)
.filter(function (k) {
return obj[k] != null;
})
.reduce(function (acc, k) {
acc[k] = typeof obj[k] === "object" ? removeEmpty(obj[k]) : obj[k];
return acc;
}, {});
}
如果你想要4行纯ES7解决方案:
const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
if (typeof v === 'boolean' || v) o[k] = clean(v);
return o;
}, e instanceof Array ? [] : {}) : e;
或者如果你喜欢更易读的版本:
function filterEmpty(obj, [key, val]) {
if (typeof val === 'boolean' || val) {
obj[key] = clean(val)
};
return obj;
}
function clean(entry) {
if (entry instanceof Object) {
const type = entry instanceof Array ? [] : {};
const entries = Object.entries(entry);
return entries.reduce(filterEmpty, type);
}
return entry;
}
这将保留布尔值,也将清理数组。它还通过返回一个清理过的副本来保存原始对象。