从Object with Underscore.js中删除空属性/假值
Remove empty properties / falsy values from Object with Underscore.js
我有一个有几个属性的对象。我想删除所有具有假值的属性。
这可以在数组上用compact
实现,但是对象呢?
从1.7.0版本开始,您可以使用_.pick
:
_.pick(sourceObj, _.identity)
_.pick
的第二个参数可以作为选择值的谓词函数。选取谓词返回为真的值,忽略谓词返回为假的值。
选择 _。选择(对象,*键)
返回对象的副本,过滤为只包含键(或有效键数组)的值。或者接受指示选择哪个键的谓词。
_.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({
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
, 还可以方便地从集合中删除空数组和对象,可能不方便地删除数字和日期。因此,结果并不是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;
},{});
为对象使用delete。
for(var k in obj){
if(obj.hasOwnProperty(k) && !obj[k]){
delete obj[k];
}
}
突然,我需要创建一个函数来删除递归错误。我希望这对你有帮助。我正在使用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'
// }
// }
我确实理解这个问题是在问如何使用下划线来做这个,但由于我来自谷歌,我想添加如何使用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;
}
});
创建一个新对象并添加键和值,而不是克隆所有内容并删除键值对。轻微的差别。
但更重要的是,显式检查null和undefined而不是falsey,这将删除值为false的键值对。
您应该使用pickBy
from 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()]
UPDATE:正如示例所示,在对象上调用_.compact
将删除键并返回一个压缩数组。
- 函数jquery.html()不提供数据属性集值
- JavaScript-获取数据属性的值返回未定义的值
- 可以使用属性赋值实现多个函数
- 如何使用JavaScript查找未定义的CSS属性的值
- 无法访问Angular Directive模板函数中的属性实际值
- 获取自定义属性的值
- 交换对象上两个属性的值
- 更改角度指令中属性的值
- 同时打印对象的属性和值Javascript
- 用javascript向数组(?)中的特定属性添加值
- 如何获取保存在变量中的HTML代码的任何属性的值
- 添加数据属性及其值以使用纯javascript进行链接
- 动态更新Angular2指令中自定义属性的值
- 为数组元素的属性赋值将设置所有其他类似元素的属性
- 为什么我得到“;无法获取属性的值'SetReturnValue'"当使用ceebox显示YouT
- 如何使用javascript获取像素中左/右/上/下属性的值
- 如何使用 jQuery 在循环中获取属性的值
- JavaScript 评估 - 如何为对象属性赋值
- 当图像和链接是 json 对象属性的值时,它们不起作用
- 从Object with Underscore.js中删除空属性/假值