我有一个包含多个属性的对象。我希望移除任何具有假值的属性。
对于数组,可以使用compact
方法来实现,但是对于对象呢?
我有一个包含多个属性的对象。我希望移除任何具有假值的属性。
对于数组,可以使用compact
方法来实现,但是对于对象呢?
_.pick
函数:_.pick(sourceObj, _.identity)
_.pick
的第二个参数可以是一个用于选择值的谓词函数。谓词返回真值的值将被选中,而谓词返回假值的值将被忽略。
pick _.pick(object, *keys)
返回object的副本,仅包含允许的keys(或有效键数组)的值。也可以接受一个指示要选择哪些键的谓词。
_.identity
是一个辅助函数,它返回其第一个参数,这意味着它也可以作为一个谓词函数,选择真值并拒绝假值。Underscore库还提供了一系列其他谓词函数,例如_.pick(sourceObj, _.isBoolean)
将仅保留布尔属性。
如果您经常使用这种技术,您可能希望使其更加表达清晰:
var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);
_.pick
,但它不接受谓词函数而只接受键列表。_.identity
函数,非常方便。 - ivkremer_.omit(sourceObj, _.isUndefined)
来仅移除 undefined 值(允许 false、null、0)。 - Ben Pattersonpick(obj, Boolean)
来消除假值,同样的方法也可以用在arr.filter(Boolean)
上,清理数组中的假值。 - David Chase_.pick(sourceObj, prop => prop)
。 (翻译者注:该代码使用了lodash库中的pick函数,用于从对象中选择指定的属性并返回一个新对象。在ES6之前的版本中,可以写成_.pick(sourceObj, _.identity)
,其中_.identity是一个返回参数本身的函数。而在ES6中,箭头函数的语法简洁明了,所以可以直接写成箭头函数的形式。) - Deniz Ozger_.pick
可以使用属性名称进行操作。如果需要此功能,请使用 _.pickBy
,如文章所述。 - zooblin你可以制作自己的下划线插件(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
underscore 方法返回一个数组的副本。
为了解决这个问题并使我们的 compactObject
表现得更像它的“表亲”,这里有一个小的更新:
_.mixin({
compactObject : function(o) {
var clone = _.clone(o);
_.each(clone, function(v, k) {
if(!v) {
delete clone[k];
}
});
return clone;
}
});
_.compact
不同。它将删除属性,而不是仅使用真值创建浅克隆。请参见下面的https://dev59.com/lGYq5IYBdhLWcg3w8lNo#19750822 - Andrei Neculaudelete
,因为它会立即暴露原型链中具有相同名称的属性,并且由于 "hidden classes"(V8),性能也会受到影响——改变对象结构会导致引擎额外工作。最好和最简短的解决方案是 _.pick(o, _.identity)
。 - Radko Dinev_.omitBy( source, i => !i );
这是对 Emil 回答的一种反向陈述。在我看来,这种方式更易于理解,更加自我说明。
如果没有 ES6 的优势,则略显不够简洁: _.omitBy( source, function(i){return !i;});
_.omitBy( source, _.isEmpty)
使用 _.isEmpty
而非 _.identity
来判断真假性时,将方便地从集合中删除空数组和对象,但也可能不便地删除数字和日期。因此,结果并不是 OP 问题的精确回答,但在寻求删除空集合时可能会有用。
omitBy
。https://lodash.com/docs#omitBy - JackMorrissey_.pick(source, i => i);
这个代码避免了否定操作。 - Jeff Lowery_.pickBy(source)
。 - Shibumi_.isEmpty(5) === true
。因此,数值将被忽略。 - Sir.Nathan Stassen使用lodash的transform函数,
_.transform(obj, function(res, v, k) {
if (v) res[k] = v;
});
var compactObject = _.partialRight(_.pick, _.identity);
。 - zaboco_.pickBy
而不是_.pick
。 - laggingreflex_.pickBy(object)
就是你所需要的。 - wdetacObject.keys(o).forEach(function(k) {
if (!o[k]) {
delete o[k];
}
});
.keys
和.forEach
操作。 - Felix KlingforEach
方法的链接。 - xkeshav_(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'
// }
// }
使用 delete 来释放对象。
for(var k in obj){
if(obj.hasOwnProperty(k) && !obj[k]){
delete obj[k];
}
}
我明白这个问题具体要求使用underscore如何实现,但是因为我从谷歌来到了这里,我想添加一下如何使用ES6来实现,并且我真的很喜欢这种方法。
Object.fromEntries(Object.entries(obj).filter(([k,v],i)=>v))
原因是它会创建一个新的对象(而不是修改先前的对象),不使用任何库,不定义任何变量,并且不会污染当前作用域。
补充gion_13的答案:
_.mixin({
compactObject : function(o) {
var newObject = {};
_.each(o, function(v, k) {
if(v !== null && v !== undefined) {
newObject[k] = v
}
});
return newObject;
}
});