如何删除JavaScript对象中undefined
或null
的所有属性?
(问题类似于数组的this one)
答案 0 :(得分:304)
使用一些 ES6 / ES2015 :
1)一个简单的单行程序,用于删除内联项而不分配:
Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);
2)此示例已删除...
3)作为函数编写的第一个示例:
const removeEmpty = (obj) => {
Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]);
}
4)此函数使用递归来删除嵌套对象中的项目:
const removeEmpty = (obj) => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key]);
else if (obj[key] == null) delete obj[key];
});
};
4b)这类似于4),但不是直接改变源对象,而是返回一个新对象。
const removeEmpty = (obj) => {
const o = JSON.parse(JSON.stringify(obj)); // Clone source oect.
Object.keys(o).forEach(key => {
if (o[key] && typeof o[key] === 'object')
o[key] = removeEmpty(o[key]); // Recurse.
else if (o[key] === undefined || o[key] === null)
delete o[key]; // Delete undefined and null.
else
o[key] = o[key]; // Copy value.
});
return o; // Return new object.
};
5)基于使用filter()
和reduce()
的{{3}}的功能性方法。这个也返回一个新对象:
const removeEmpty = (obj) =>
Object.keys(obj)
.filter(k => obj[k] !== null && obj[k] !== undefined) // Remove undef. and null.
.reduce((newObj, k) =>
typeof obj[k] === 'object' ?
Object.assign(newObj, {[k]: removeEmpty(obj[k])}) : // Recurse.
Object.assign(newObj, {[k]: obj[k]}), // Copy value.
{});
6)与4)相同,但 ES7 / 2016 jsbin。
const removeEmpty = (obj) =>
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val === 'object') removeEmpty(val)
else if (val == null) delete obj[key]
})
7)与4)相同,但在简单的 ES5 :
function removeEmpty(obj) {
Object.keys(obj).forEach(function(key) {
if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
else if (obj[key] == null) delete obj[key]
});
};
答案 1 :(得分:130)
您可以遍历对象:
var test = {
test1 : null,
test2 : 'somestring',
test3 : 3,
}
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
clean(test);
如果您担心此属性删除没有运行对象的proptype链,您还可以:
function clean(obj) {
var propNames = Object.getOwnPropertyNames(obj);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
关于null vs undefined的一些注释:
test.test1 === null; // true
test.test1 == null; // true
test.notaprop === null; // false
test.notaprop == null; // true
test.notaprop === undefined; // true
test.notaprop == undefined; // true
答案 2 :(得分:74)
如果您使用的是lodash或underscore.js,这是一个简单的解决方案:
var obj = {name: 'John', age: null};
var compacted = _.pickBy(obj);
这只适用于lodash 4,pre lodash 4或underscore.js,使用_.pick(obj, _.identity)
;
答案 3 :(得分:34)
如果有人需要Owen's(和Eric's)答案的递归版本,那么它就是:
/**
* Delete all null (or undefined) properties from an object.
* Set 'recurse' to true if you also want to delete properties in nested objects.
*/
function delete_null_properties(test, recurse) {
for (var i in test) {
if (test[i] === null) {
delete test[i];
} else if (recurse && typeof test[i] === 'object') {
delete_null_properties(test[i], recurse);
}
}
}
答案 4 :(得分:33)
用于ES6 +的最短衬板
过滤所有伪造的值(“”,0,false,null,undefined)
Object.entries(obj).reduce((a,[k,v]) => (v ? {...a, [k]:v} : a), {})
过滤null和未定义的值:
Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : {...a, [k]:v}), {})
仅过滤null
Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : {...a, [k]:v}), {})
仅过滤器未定义
Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : {...a, [k]:v}), {})
递归:过滤空值和未定义
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}), {});
答案 5 :(得分:15)
JSON.stringify删除未定义的键。
removeUndefined = function(json){
return JSON.parse(JSON.stringify(json))
}
答案 6 :(得分:13)
您可能正在寻找delete
关键字。
var obj = { };
obj.theProperty = 1;
delete obj.theProperty;
答案 7 :(得分:7)
您可以使用JSON.stringify
,其替换参数和JSON.parse
的组合将其重新转换为对象。使用此方法还意味着替换嵌套对象中的所有嵌套键。
示例对象
var exampleObject = {
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3],
object: {
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
arrayOfObjects: [
{
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
{
string: 'value',
emptyString: '',
integer: 0,
nullValue: null,
array: [1, 2, 3]
}
]
};
替换功能
function replaceUndefinedOrNull(key, value) {
if (value === null || value === undefined) {
return undefined;
}
return value;
}
清理对象
exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);
答案 8 :(得分:6)
最简单的Lodash解决方案,用于返回已过滤掉null
和undefined
值的对象。
_.omitBy(obj, _.isNil)
答案 9 :(得分:5)
使用ramda#pickBy,您将删除所有null
,undefined
和false
值:
const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)
正如@manroe指出的那样,要保持false
值使用isNil()
:
const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)
答案 10 :(得分:5)
更短的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; }, {});
答案 11 :(得分:4)
我的项目中有相同的场景,并使用以下方法实现。
它适用于所有数据类型,上面提到的少数数据不适用于日期和空数组。
<强> removeEmptyKeysFromObject.js 强>
removeEmptyKeysFromObject(obj) {
Object.keys(obj).forEach(key => {
if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
delete obj[key];
} else if (obj[key] && typeof obj[key] === 'object') {
this.removeEmptyKeysFromObject(obj[key]);
} else if (obj[key] == null || obj[key] === '') {
delete obj[key];
}
if (obj[key]
&& typeof obj[key] === 'object'
&& Object.keys(obj[key]).length === 0
&& Object.prototype.toString.call(obj[key]) !== '[object Date]') {
delete obj[key];
}
});
return obj;
}
将任何对象传递给此函数removeEmptyKeysFromObject()
答案 12 :(得分:4)
如果你想要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;
}
这将保留布尔值,它也将清理数组。它还通过返回已清理的副本来保留原始对象。
答案 13 :(得分:3)
删除所有带有 null 和 undefined 的属性
let obj = {
"id": 1,
"firstName": null,
"lastName": null,
"address": undefined,
"role": "customer",
"photo": "fb79fd5d-06c9-4097-8fdc-6cebf73fab26/fc8efe82-2af4-4c81-bde7-8d2f9dd7994a.jpg",
"location": null,
"idNumber": null,
};
let result = Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});
console.log(result)
答案 14 :(得分:3)
reduce助手可以解决问题(无需类型检查)-
const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
if (value) {
acc[key] = value;
}
return acc;
}, {});
答案 15 :(得分:3)
对于深度搜索,我使用了以下代码,可能对于任何查看此问题的人都有用(它不适用于循环依赖):
function removeEmptyValues(obj) {
for (var propName in obj) {
if (!obj[propName] || obj[propName].length === 0) {
delete obj[propName];
} else if (typeof obj[propName] === 'object') {
removeEmptyValues(obj[propName]);
}
}
return obj;
}
答案 16 :(得分:3)
要在Ben's answer上使用lodash的_.pickBy
来解决这个问题,你也可以在姐妹库中解决这个问题:Underscore.js的_.pick
。< / p>
var obj = {name: 'John', age: null};
var compacted = _.pick(obj, function(value) {
return value !== null && value !== undefined;
});
请参阅:JSFiddle Example
答案 17 :(得分:2)
如果您不想在适当的位置进行变异,但返回删除了null / undefined的克隆,则可以使用ES6 reduce函数。
// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
// Protect against null/undefined object passed in
return Object.keys(obj || {}).reduce((x, k) => {
// Check for null or undefined
if (obj[k] != null) {
x[k] = obj[k];
}
return x;
}, {});
}
答案 18 :(得分:2)
您可以使用!
条件
var r = {a: null, b: undefined, c:1};
for(var k in r)
if(!r[k]) delete r[k];
请记住使用情况:@semicolor在评论中宣布:如果值为空字符串,则还会删除属性,false或为零
答案 19 :(得分:2)
如果有人需要使用undefined
通过深度搜索从对象中删除lodash
值,那么这就是我正在使用的代码。修改它以删除所有空值(null
/ undefined
)非常简单。
function omitUndefinedDeep(obj) {
return _.reduce(obj, function(result, value, key) {
if (_.isObject(value)) {
result[key] = omitUndefinedDeep(value);
}
else if (!_.isUndefined(value)) {
result[key] = value;
}
return result;
}, {});
}
答案 20 :(得分:2)
您也可以使用非空的键创建一个新对象,而不是删除该属性。
const removeEmpty = (obj) => {
return Object.keys(obj).filter(key => obj[key]).reduce(
(newObj, key) => {
newObj[key] = obj[key]
return newObj
}, {}
)
}
答案 21 :(得分:1)
这是一种使用ES6从对象中删除nulls
而不用仅使用reduce
进行对象变异的功能方法:
const stripNulls = (obj) => {
return Object.keys(obj).reduce((acc, current) => {
if (obj[current] !== null) {
return { ...acc, [current]: obj[current] }
}
return acc
}, {})
}
答案 22 :(得分:1)
这是另一种选择
打字稿:
function objectDefined <T>(obj: T): T {
const acc: Partial<T> = {};
for (const key in obj) {
if (obj[key] !== undefined) acc[key] = obj[key];
}
return acc as T;
}
JavaScript:
function objectDefined(obj) {
const acc = {};
for (const key in obj) {
if (obj[key] !== undefined) acc[key] = obj[key];
}
return acc;
}
答案 23 :(得分:1)
这个问题已经得到了彻底的回答,我只想根据给出的其他示例贡献我的版本:
function filterObject(obj, filter) {
return Object.entries(obj)
.map(([key, value]) => {
return [key, value && typeof value === 'object'
? filterObject(value, filter)
: value];
})
.reduce((acc, [key, value]) => {
if (!filter.includes(value)) {
acc[key] = value;
}
return acc;
}, {});
}
此解决方案与众不同之处在于可以在第二个参数中指定要过滤的值,如下所示:
const filtered = filterObject(originalObject, [null, '']);
将返回不包含值为null
或''
的属性的新对象(不对原始对象进行突变)。
答案 24 :(得分:1)
这是一个全面的递归函数(最初基于@chickens的递归函数),它将:
defaults=[undefined, null, '', NaN]
的内容const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
if (!defaults.length) return obj
if (defaults.includes(obj)) return
if (Array.isArray(obj))
return obj
.map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
.filter(v => !defaults.includes(v))
return Object.entries(obj).length
? Object.entries(obj)
.map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
.reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {})
: obj
}
用法:
// based off the recursive cleanEmpty function by @chickens.
// This one can also handle Date objects correctly
// and has a defaults list for values you want stripped.
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
if (!defaults.length) return obj
if (defaults.includes(obj)) return
if (Array.isArray(obj))
return obj
.map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
.filter(v => !defaults.includes(v))
return Object.entries(obj).length
? Object.entries(obj)
.map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
.reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {})
: obj
}
// testing
console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
a: 5,
b: 0,
c: undefined,
d: {
e: null,
f: [{
a: undefined,
b: new Date(),
c: ''
}]
},
g: NaN,
h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
a: 5,
b: 0,
c: undefined,
d: {
e: null,
f: [{
a: undefined,
b: '',
c: new Date()
}]
},
g: [0, 1, 2, 3, 4],
h: '',
}, [undefined, null]))
答案 25 :(得分:1)
如果您使用eslint并希望避免使用无参数重新分配规则,可以将Object.assign与.reduce结合使用,并将计算属性名称用于相当优雅的ES6解决方案:
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 }
答案 26 :(得分:1)
您还可以使用...
的{{1}}扩展语法,如下所示:
forEach
答案 27 :(得分:1)
通常,我们希望获得一个不包含某些值的新对象。 Usign ES7:
const getObjWithoutVals = (dontReturnValsArr, obj) => (
Object.entries(obj).reduce(
(newObj, [key, val]) => {
if(!dontReturnValsArr.includes(val)) newObj[key]= val
return newObj
}
, {}
)
)
首先让我们管理我们的功能,以便在这种情况下使用它。
const curriedGetObjWithout = R.curry(getObjWithoutVals)
现在让我们创建一个排除空值的新函数
const getObjWithoutEmpty = curriedGetObjWithout(["", null, undefined])
答案 28 :(得分:0)
您可以使用json.stringify's replacer argument
在一行中进行递归删除const removeNullValues = obj => (
JSON.parse(JSON.stringify(obj, (k,v) => v==null?undefined:v))
)
用法:
removeNullValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}
答案 29 :(得分:0)
以递归方式删除null,未定义,空对象和空数组,并返回副本(ES6版本)
export function skipEmpties(dirty) {
let item;
if (Array.isArray(dirty)) {
item = dirty.map(x => skipEmpties(x)).filter(value => value !== undefined);
return item.length ? item : undefined;
} else if (dirty && typeof dirty === 'object') {
item = {};
Object.keys(dirty).forEach(key => {
const value = skipEmpties(dirty[key]);
if (value !== undefined) {
item[key] = value;
}
});
return Object.keys(item).length ? item : undefined;
} else {
return dirty === null ? undefined : dirty;
}
}
答案 30 :(得分:0)
功能和不变的方法,没有.filter
,并且没有创建超出需要的对象
Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})
答案 31 :(得分:0)
我们可以使用JSON.stringify和JSON.parse从对象中删除空白属性。
PATCH https://dev.azure.com/{project}/_apis/wit/workitems/{id}?api-version=5.0
答案 32 :(得分: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 }));
filter(key => objectWithNulls[key])
返回真实的所有内容,因此将拒绝诸如0
或false
以及undefined
或null
。如果这是不必要的行为,可以轻松更改为filter(key => objectWithNulls[key] !== undefined)
或类似的内容。
答案 33 :(得分:0)
如果您只想从对象中删除未定义的顶级属性,我认为这是最简单的:
const someObject = {
a: null,
b: 'someString',
c: 3,
d: undefined
};
for (let [key, value] of Object.entries(someObject)) {
if (value === null || value === undefined) delete someObject[key];
}
console.log('Sanitized', someObject);
答案 34 :(得分:0)
ES6 arrow function and ternary operator:
Object.entries(obj).reduce((acc, entry) => {
const [key, value] = entry
if (value !== undefined) acc[key] = value;
return acc;
}, {})
const obj = {test:undefined, test1:1 ,test12:0, test123:false};
const newObj = Object.entries(obj).reduce((acc, entry) => {
const [key, value] = entry
if (value !== undefined) acc[key] = value;
return acc;
}, {})
console.log(newObj)
答案 35 :(得分:0)
如果您喜欢纯粹/实用的方法
const stripUndef = obj =>
Object.keys(obj)
.reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
答案 36 :(得分:0)
删除空字段对象
for (const objectKey of Object.keys(data)) {
if (data[objectKey] === null || data[objectKey] === '' || data[objectKey] === 'null' || data[objectKey] === undefined) {
delete data[objectKey];
}
}
答案 37 :(得分:0)
Lodash:
_.omitBy({a: 1, b: null}, (v) => !v)
答案 38 :(得分:0)
如果可以使用Lodash,可以添加DeepDash递归库,并通过一些简洁的代码来实现所需的功能:
const prune = obj => _.filterDeep(obj, (v) => !(_.isUndefined(v) || _.isNull(v)));
调用prune(anObjectWithNulls)
将返回没有undefined
或null
值的对象。
答案 39 :(得分:-1)
30多个答案,但是我没有看到这个简短的ES6线性代码,因为Object.assign()
是一个无变量忽略任何非对象(如false
)的vararg函数,所以使用了散布运算符。
Object.assign({}, ...Object.entries(obj).map(([k,v]) => v != null && {[k]: v]))