从Javascript中的对象中删除空白属性
如何删除JavaScript对象中undefined
或null
所有属性?
(问题与arrays的问题类似)
你可以遍历对象:
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与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
使用一些ES6 / ES2015 :
1)一个简单的单线程删除项目“内联”没有分配:
Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);
jsbin
2)具有即时variables分配的版本。 这使用一个数组来实现在一个声明中的删除和返回:
let newObj = [Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]), obj][1]
jsbin
3)作为函数写的第一个例子:
const removeEmpty = (obj) => { Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]); return obj; }
jsbin
4)这个函数也使用recursion从嵌套对象中删除项目:
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]; }); return obj; };
jsbin
5)基于@ MichaelJ.Zoidl的使用filter()
和reduce()
的回答的更多function方法4)
const removeEmpty = (obj) => Object.keys(obj) .filter(f => obj[f] != null) .reduce((r, i) => typeof obj[i] === 'object' ? {...r, [i]: removeEmpty(obj[i])) : // recurse. {...r, [i]: obj[i]}, {});
jsbin
6)与4)相同,但使用ES7 / 2016 Object.entries
。
const removeEmpty = (obj) => { Object.entries(obj).forEach(([key, val]) => if (val && typeof val === 'object') removeEmpty(val) else if (val == null) delete obj[key] ); return obj; };
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] }); return obj; };
jsbin
如果您使用lodash或underscore.js,这是一个简单的解决scheme:
var obj = {name: 'John', age: null}; var compacted = _.pickBy(obj);
这将只适用于lodash 4,pre lodash 4或underscore.js,使用_.pick(obj, _.identity)
. _.pick(obj, _.identity)
;
如果有人需要欧文(和埃里克)答案的recursion版本,这里是:
/** * 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); } } }
您可能正在寻找delete
关键字。
var obj = { }; obj.theProperty = 1; delete obj.theProperty;
JSON.stringify删除未定义的键。
removeUndefined = function(json){ return JSON.parse(JSON.stringify(json)) }
您可以使用JSON.stringify
,其replacer参数和JSON.parse
的组合将其重新转换为对象。 使用这种方法也意味着对嵌套对象中的所有嵌套键进行replace。
示例对象
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
function replaceUndefinedOrNull(key, value) { if (value === null || value === undefined) { return undefined; } return value; }
清洁对象
exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull); exampleObject = JSON.parse(exampleObject);
CodePen例子
较短的ES6纯粹的解决scheme,将其转换为数组,使用过滤function,并将其转换回对象。 也很容易做出function…
顺便说一句。 这个.length > 0
我检查是否有一个空的string/数组,所以它会删除空的键。
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; }, {});
对于深度search,我使用了下面的代码,也许这对于查看这个问题的任何人都是有用的(它对循环依赖不可用):
function removeEmptyValues(obj) { for (var propName in obj) { if (!obj[propName] || obj[propName].length === 0) { delete obj[propName]; } else if (typeof obj === 'object') { removeEmptyValues(obj[propName]); } } return obj; }
使用ramda#pickBy :
const obj = {a:1, b: undefined, c: null, d: 1} R.pickBy(R.identity, obj)
您也可以使用不为空的键创build一个新对象,而不是删除该属性。
const removeEmpty = (obj) => { return Object.keys(obj).filter(key => obj[key]).reduce( (newObj, key) => { newObj[key] = obj[key] return newObj }, {} ) }
你可以做得更短!
条件
var r = {a: null, b: undefined, c:1}; for(var k in r) if(!r[k]) delete r[k];
记住用法:@ semicolor在注释中宣布: 如果值是空string,则这也会删除属性,为false或为零
为了在Ben的答案中用lodash的_.pickBy
来解决这个问题,你也可以在姊妹库中解决这个问题: _.pick
。
var obj = {name: 'John', age: null}; var compacted = _.pick(obj, function(value) { return value !== null && value !== undefined; });
请参阅: JSFiddle示例
如果您不想在原地进行变异,但是返回一个删除了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; }, {}); }
最简单的Lodash解决scheme返回一个对象的null
和undefined
值过滤掉。
_.omitBy(obj, _.isNil)
如果您使用eslint并希望避免跳过no-param-resssign规则,则可以将Object.assign与.reduce和一个计算的属性名称结合使用,以获得相当优雅的ES6解决scheme:
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 }
这个函数可以在清除对象或数组内的invidival emptys后清空这个空对象。 这可以确保您没有空的数组或对象。
function removeNullsInObject(obj) { if( typeof obj === 'string' || obj === "" ){ return; } $.each(obj, function(key, value){ if (value === "" || value === null){ delete obj[key]; } else if ($.isArray(value)) { if( value.length === 0 ){ delete obj[key]; return; } $.each(value, function (k,v) { removeNullsInObject(v); }); if( value.length === 0 ){ delete obj[key]; } } else if (typeof value === 'object') { if( Object.keys(value).length === 0 ){ delete obj[key]; return; } removeNullsInObject(value); if( Object.keys(value).length === 0 ){ delete obj[key]; } } }); }
如果有人需要使用lodash
从深度search对象中删除undefined
值,那么这里是我正在使用的代码。 修改它以删除所有空值( 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; }, {}); }
下面的解决scheme删除null
以及empty object
empty object
或{}
是由于null
清除而导致的残留
要清理一个对象使用下面
/** * 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 || test[i] === undefined) { delete test[i]; } // recurse for array and object else if (recurse && typeof test[i] === 'object') { test[i] = delete_null_properties(test[i], recurse); } if((test[i] && typeof(test[i]) === 'object') && (Object.keys(test[i]).length === 0 || test[i] == [{}])) { // delete the child property if its empty delete test[i] } if(test == {}){ // delete empty 'parent' object when there is a residue due to deletion // of its child properties delete test } else if(test instanceof Array && test[i] == undefined) { // in the case of array removed null childs by splicing it off test.splice(i,1) // however if the parent array itself goes empty remove it off if(test instanceof Array && test.length == 0) { test = null } } } return test } delete_null_properties(obj, true)
随着Lodash:
_.omitBy({a: 1, b: null}, (v) => !v)
您可以使用此对象清除组件来清除所有对象的虚假属性,并在没有它们的情况下返回一个新对象。
例子:
new cleaned object clean({ foo: null, bar: 'foo' }) // => { bar: 'foo' }
如果您需要4条纯ES7解决scheme:
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; }
这将保存布尔值,它也会清理数组。 它还通过返回一个干净的副本来保留原始对象。
我在我的项目中有相同的场景,并使用以下方法实现。
它适用于所有数据types,上面提到的几个不适用于date和空数组。
removeEmptyKeysFromObject.js
removeEmptyKeysFromObject(obj) { Object.keys(obj).forEach(key => { if (Object.prototype.toString.call(obj[key]) === '[object Date]' && obj[key].toString().length === 0) { 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; }
存在一个简单的方法来执行这个任务。 这完成使用jQuery方法$.grep
。
var test = { a: null, b: 'hello world', c: 12345 } var newTest = $.grep( test, function(element, index) { return (test[element] && test[element] != null); } ); // newTest = { b: 'hello world', c: 12345 }
$.grep
查找满足过滤函数的数组的元素。在这种情况下,任何非空的属性