我有一个具有多个属性的对象。我想删除任何具有虚假值的属性。
这可以通过compact
on 数组来实现,但是对象呢?
从下划线版本 1.7.0 开始,您可以使用_.pick
:
_.pick(sourceObj, _.identity)
第二个参数_.pick
可以是用于选择值的谓词函数。选择谓词返回真值的值,而忽略谓词返回假值的值。
挑选_.pick(对象,*键)
返回object的副本,过滤后仅包含白名单键(或有效键数组)的值。或者接受一个谓词,指示选择哪些键。
_.identity
是一个辅助函数,它返回它的第一个参数,这意味着它也可以作为一个谓词函数来选择真值并拒绝假值。Underscore 库还附带了许多其他谓词,例如_.pick(sourceObj, _.isBoolean)
仅保留布尔属性。
如果你经常使用这种技术,你可能想让它更有表现力:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
也提供了下划线版本 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 指出的那样,这个mixin 会影响原始对象,而原始的compact
下划线方法会返回数组的副本。
为了解决这个问题并使我们的compactObject
行为更像它的表亲,这里有一个小的更新:
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
_.omitBy( source, i => !i );
这与埃米尔的回答相反。这样,恕我直言,读起来更清楚;它更不言自明。
如果您没有 ES6 的奢华,那么清洁度会稍微低一些:_.omitBy( source, function(i){return !i;});
_.omitBy( source, _.isEmpty)
使用_.isEmpty
,而不是_.identity
真实性,也可以方便地从集合中删除空数组和对象,并且可能不方便地删除 numbers 和 dates。因此,结果不是对 OP 问题的确切答案,但是在寻找删除空集合时它可能很有用。
使用 lodash 的变换,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
Object.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
您可以创建一个浅克隆:
_(obj).reduce(function(a,v,k){
if(v){ a[k]=v; }
return a;
},{});
突然间,我需要创建一个函数来递归地删除 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'
// }
// }
对于对象使用删除。
for(var k in obj){
if(obj.hasOwnProperty(k) && !obj[k]){
delete obj[k];
}
}
要添加到 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 作为值的键值对。
你应该pickBy
从 lodash 使用。
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
对象将删除键并返回压缩数组。