如何使用lodash从对象中删除未定义和空值?
我有一个JavaScript对象,如:
var my_object = { a:undefined, b:2, c:4, d:undefined };
如何删除所有未定义的属性?
如果你想删除所有错误的值,那么最紧凑的方式是:
_.pick(obj, _.identity);
例如(Lodash 3.x):
_.pick({ a: null, b: 1, c: undefined }, _.identity); >> Object {b: 1}
对于Lodash 4.x:
_.pickBy({ a: null, b: 1, c: undefined }, _.identity); >> Object {b: 1}
你可以简单地链接_.omit()
和_.isUndefined
和_.isNull
作文,并得到结果懒惰的评价。
演示
var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();
2016年3月14日更新 :
正如注释部分中的dylants所提到的,您应该使用_.omitBy()
函数,因为它使用谓词而不是属性。 你应该使用这个lodash版本4.0.0
及以上。
DEMO
var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
2016年6月1日更新 :
正如Max Truxa评论的,lodash已经提供了一个替代_.isNil
。
var result = _.omitBy(my_object, _.isNil);
如果您使用lodash,则可以使用_.compact(array)
从数组中删除所有错误的值。
_.compact([0, 1, false, 2, '', 3]); // => [1, 2, 3]
只是:
_.omit(my_object, _.isUndefined)
上面没有考虑到null
值,因为它们是从原来的例子中缺less的,只在主题中提到,但是我把它留下来,因为它很优雅,可能有它的用途。
这是一个完整的例子,不太简洁,但更完整。
var obj = { a: undefined, b: 2, c: 4, d: undefined, e: null, f: false, g: '', h: 0 }; console.log(_.omit(obj, function(v) { return _.isUndefined(v) || _.isNull(v); }));
根据lodash文档:
_.compact(_.map(array, fn))
你也可以过滤掉所有的空值
这是我采取的方法:
_(my_object) .pairs() .reject(function(item) { return _.isUndefined(item[1]) || _.isNull(item[1]); }) .zipObject() .value()
pairs()函数将input对象转换为键/值数组的数组。 你这样做是为了更容易地使用reject()来消除undefined
和null
值。 之后,你剩下的对没有被拒绝,这些input为zipObject() ,它为你重build你的对象。
考虑到undefined == null
我们可以这样写:
let collection = { a: undefined, b: 2, c: 4, d: null, } console.log(_.omit(collection, it => it == null)) // -> { b: 2, c: 4 }
JSBin的例子
我遇到了一个类似的问题,就是从对象(深层)中删除undefined
的对象,并发现如果您可以转换普通的旧对象并使用JSON,那么一个快速又脏兮兮的辅助函数看起来像这样:
function stripUndefined(obj) { return JSON.parse(JSON.stringify(obj)); }
“…如果未定义,在转换过程中遇到函数或符号,则会将其忽略(在对象中find该对象时)或将其删除(在数组中find它时)。
用lodash(或下划线)你可以这样做
var my_object = { a:undefined, b:2, c:4, d:undefined, e:null }; var passedKeys = _.reject(Object.keys(my_object), function(key){ return _.isUndefined(my_object[key]) || _.isNull(my_object[key]) }) newObject = {}; _.each(passedKeys, function(key){ newObject[key] = my_object[key]; });
否则,用香草JavaScript,你可以做
var my_object = { a:undefined, b:2, c:4, d:undefined }; var new_object = {}; Object.keys(my_object).forEach(function(key){ if (typeof my_object[key] != 'undefined' && my_object[key]!=null){ new_object[key] = my_object[key]; } });
不要使用虚假的testing,因为不仅“undefined”或“null”将被拒绝 ,还有其他falsey值如“false”,“0”,空string{}。 因此,为了使其简单易懂,我select使用上面编码的显式比较。
var my_object = { a:undefined, b:2, c:4, d:undefined }; var newObject = _.reject(my_collection, function(val){ return _.isUndefined(val) }) //--> newCollection = { b: 2, c: 4 }
我会使用下划线和照顾空string:
var my_object = { a:undefined, b:2, c:4, d:undefined, k: null, p: false, s: '', z: 0 }; var result =_.omit(my_object, function(value) { return _.isUndefined(value) || _.isNull(value) || value === ''; }); console.log(result); //Object {b: 2, c: 4, p: false, z: 0}
(尽pipeObject.entries是ES7,Object.assign是ES6;但是相同的ES5使用Object.keys也应该是可行的)。 也注意v != null
检查null和undefined;
> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: 0.3, s: "", t: false }; undefined > Object.entries(d) .filter(([ k, v ]) => (v != null)) .reduce((acc, [k, v]) => Object.assign(acc, {[k]: v}), {}) { b: 2, c: 0, f: 0.3, s: '', t: false }
编辑:这下面是只有ES5 Object.keys的版本:但通常在节点v8 ES7是非常愉快的;-)
> Object.keys(d) .filter(function(k) { return d[k] != null; }) .reduce(function(acc, k) { acc[k] = d[k]; return acc; }, {}); { b: 2, c: 0, f: 0.3, s: '', t: false }
2017年10月更新 :使用Node v8(自v8.3版本起)现在它具有对象扩展构造:
> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: -0.0, s: "", t: false, inf: +Infinity, nan: NaN }; undefined > Object.entries(d) .filter(([ k, v ]) => (v != null)) .reduce((acc, [k, v]) => ({...acc, [k]: v}), {}) { b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }
或者只在一个范围内减less:
> Object.entries(d) .reduce((acc, [k, v]) => (v==null ? acc : {...acc, [k]: v}), {}) { b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }
更新:有人想recursion? 不是那么辛苦,只需要一个额外的isObject检查,并recursion调用自己:
> function isObject(o) { return Object.prototype.toString.call(o) === "[object Object]"; } undefined > function dropNullUndefined(d) { return Object.entries(d) .reduce((acc, [k, v]) => ( v == null ? acc : {...acc, [k]: (isObject(v) ? dropNullUndefined(v) : v) } ), {}); } > dropNullUndefined({a: 3, b:null}) { a: 3 } > dropNullUndefined({a: 3, b:null, c: { d: 0, e: undefined }}) { a: 3, c: { d: 0 } }
我的结论是:如果纯Javascript可以做,我会避免任何第三方库依赖: