如何删除JavaScript对象中未定义或空的所有属性?
(这个问题与数组的问题类似)
如何删除JavaScript对象中未定义或空的所有属性?
(这个问题与数组的问题类似)
当前回答
ES6+的最短一行
过滤所有错误值("",0,false, null, undefined)
Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})
过滤空值和未定义值:
Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})
仅过滤null
Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})
过滤器仅未定义
Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})
递归解决方案:过滤null和undefined
对象:
const cleanEmpty = obj => Object.entries(obj)
.map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
.reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});
对于对象和数组:
const cleanEmpty = obj => {
if (Array.isArray(obj)) {
return obj
.map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
.filter(v => !(v == null));
} else {
return Object.entries(obj)
.map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
.reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
}
}
其他回答
如果你使用eslint并且想要避免绊倒no-param-reassign规则,你可以使用Object。对于一个相当优雅的ES6解决方案,assign与.reduce和计算属性名结合使用:
const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams)
.filter(key => queryParams[key] != null)
.reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }
下面是一个使用ES6从对象中删除null值的函数式方法,而不需要只使用reduce来改变对象:
const stripNulls = (obj) => {
return Object.keys(obj).reduce((acc, current) => {
if (obj[current] !== null) {
return { ...acc, [current]: obj[current] }
}
return acc
}, {})
}
你可以剪短一点!条件
var r = {a: null, b: undefined, c:1};
for(var k in r)
if(!r[k]) delete r[k];
使用时请记住:as @分色announcement in comments:如果值为空字符串、false或0,这也会删除属性
如果你不想修改原始对象(使用一些ES6操作符):
const keys = Object.keys(objectWithNulls).filter(key => objectWithNulls[key]);
const pairs = keys.map(key => ({ [key]: objectWithNulls[key] }));
const objectWithoutNulls = pairs.reduce((val, acc) => ({ ...val, ...acc }));
过滤器(key => objectWithNulls[key])返回任何为真值的值,因此将拒绝任何值,如0或false,以及undefined或null。可以很容易地更改为过滤器(key => objectWithNulls[key] !== undefined)或类似的东西,如果这是不想要的行为。
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;
}, {});
}