我有一个具有多个属性的对象。我想删除任何具有虚假值的属性。
这可以通过数组上的 compact
来实现,但是对象呢?
从 Underscore 版本 1.7.0 开始,您可以使用 _.pick
:
_.pick(sourceObj, _.identity)
解释
_.pick
的第二个参数可以是用于选择值的谓词函数。选择谓词返回 truthy 的值,忽略谓词返回 falsy 的值。
pick _.pick(object, *keys) 返回对象的副本,过滤后仅包含白名单键(或有效键数组)的值。或者接受一个谓词,指示选择哪些键。
_.identity
是一个辅助函数,它返回它的第一个参数,这意味着它也可以作为一个谓词函数来选择真值并拒绝假值。 Underscore 库还附带了许多其他谓词,例如 _.pick(sourceObj, _.isBoolean)
将仅保留布尔属性。
如果你经常使用这种技术,你可能想让它更有表现力:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
Underscore 版本 1.6.0 也提供了 _.pick
,但它不接受谓词函数而不是白名单。
您可以制作自己的下划线插件(mixin):
_.mixin({
compactObject: function(o) {
_.each(o, function(v, k) {
if(!v) {
delete o[k];
}
});
return o;
}
});
然后将其用作本机下划线方法:
var o = _.compactObject({
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined
});
更新
与 @AndreiNeculau pointed out 一样,此 mixin 会影响原始对象,而原始 compact
下划线方法 returns a copy of the array。
为了解决此问题并使我们的 compactObject
表现得更像它的表亲 em>,这里有一个小更新:
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
_.compact
。它将删除属性,而不是创建仅具有真实值的浅层克隆。请参阅下面的stackoverflow.com/a/19750822/465684
delete
,因为它会立即从原型链中公开具有相同名称的属性,并且还会由于“隐藏类”(V8)而损害性能 - 更改对象结构会导致引擎做额外的工作。最好和最短的解决方案是_.pick(o, _.identity)
。
快速清除:_.omitBy(source, i => !i);
这与埃米尔的回答相反。这样,恕我直言,读起来更清楚;它更不言自明。
如果您没有 ES6 的奢华,那么清洁度会稍差:_.omitBy( source, function(i){return !i;});
备选:_.omitBy(source, _.isEmpty)
使用 _.isEmpty
而不是 _.identity
来保证真实性,还可以方便地从集合中删除空数组和对象,并且可能不方便地删除数字和日期。因此,结果不是对 OP 问题的确切答案,但是在寻找删除空集合时它可能很有用。
omitBy
下。 lodash.com/docs#omitBy
_.pick(source, i => i);
相同
_.pickBy(source)
就是所需要的。
_.isEmpty(5) === true
。因此,数字值将被删除。
使用 lodash 的 transform,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
var compactObject = _.partialRight(_.pick, _.identity);
_.pickBy(object)
Object.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
.keys
和 .forEach
可以使用下划线。
forEach
方法的链接
您可以创建一个浅克隆:
_(obj).reduce(function(a,v,k){
if(v){ a[k]=v; }
return a;
},{});
对于对象使用删除。
for(var k in obj){
if(obj.hasOwnProperty(k) && !obj[k]){
delete obj[k];
}
}
突然间,我需要创建一个函数来递归地删除 falsies。我希望这有帮助。我正在使用 Lodash。
var removeFalsies = function (obj) {
return _.transform(obj, function (o, v, k) {
if (v && typeof v === 'object') {
o[k] = _.removeFalsies(v);
} else if (v) {
o[k] = v;
}
});
};
_.mixin({ 'removeFalsies': removeFalsies });
然后你可以使用它:
var o = _.removeFalsies({
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined,
obj: {
foo: 'bar',
a: 0,
b: false,
c: '',
d: null,
e: undefined
}
});
// {
// foo: 'bar',
// obj: {
// foo: 'bar'
// }
// }
要添加到 gion_13 的答案:
_.mixin({
compactObject : function(o) {
var newObject = {};
_.each(o, function(v, k) {
if(v !== null && v !== undefined) {
newObject[k] = v
}
});
return newObject;
}
});
这个创建一个新对象并添加键和值,而不是克隆所有内容并删除键值对。细微差别。
但更重要的是,显式检查 null 和 undefined 而不是 false,这将删除具有 false 作为值的键值对。
您应该使用 lodash 中的 pickBy
。
pickBy 的默认签名是 _.(sourceObj, [_.identity])
,因此它将删除空属性
_.pickBy(sourceObj);
在 lodash 你这样做:
_.pickBy(object, _.identity);
尽管记录了 _.compact
可在数组中使用。它似乎也适用于对象。我刚刚在 chrome、opera 和 firefox 控制台中运行了以下命令:
var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)
[1, 3, function()]
更新:由于示例表明在对象上调用 _.compact
将删除键并返回压缩数组。
_.identity
功能,非常好用。_.omit(sourceObj, _.isUndefined)
仅删除未定义的值(允许 false、null、0)。pick(obj, Boolean)
来消除错误值,当arr.filter(Boolean)
清除数组中的错误值时,可以使用相同的方法......_.pick(sourceObj, prop => prop)
_.pick
与属性名称一起使用,对于帖子使用_.pickBy
中提到的此功能