87

我有一个具有多个属性的对象。我想删除任何具有虚假值的属性。

这可以通过compacton 数组来实现,但是对象呢?

4

12 回答 12

171

从下划线版本 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,但它不接受谓词函数而不是白名单。

于 2014-10-10T08:45:44.470 回答
48

您可以制作自己的下划线插件(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;
  }
});
于 2012-12-27T17:08:14.537 回答
46

快速清除:_.omitBy( source, i => !i );

这与埃米尔的回答相反。这样,恕我直言,读起来更清楚;它更不言自明。

如果您没有 ES6 的奢华,那么清洁度会稍微低一些:_.omitBy( source, function(i){return !i;});

备用:_.omitBy( source, _.isEmpty)

使用_.isEmpty,而不是_.identity真实性,也可以方便地从集合中删除空数组和对象,并且可能不方便地删除 numbers 和 dates。因此,结果不是对 OP 问题的确切答案,但是在寻找删除空集合时它可能很有用。

于 2015-09-03T22:23:16.527 回答
21

使用 lodash 的变换

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});
于 2014-05-17T07:13:22.280 回答
19
Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});
于 2012-12-27T16:55:59.840 回答
9

您可以创建一个浅克隆:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});
于 2013-11-03T07:35:40.950 回答
5

突然间,我需要创建一个函数来递归地删除 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'
//   }
// }
于 2015-04-10T22:55:01.423 回答
5

对于对象使用删除。

for(var k in obj){

  if(obj.hasOwnProperty(k) && !obj[k]){
    delete obj[k];
  }
}
于 2012-12-27T16:55:35.303 回答
1

要添加到 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 作为值的键值对。

于 2015-02-06T00:46:41.787 回答
1

你应该pickBy从 lodash 使用。

pickBy 的默认签名是_.(sourceObj, [_.identity])这样它会删除空属性

_.pickBy(sourceObj);
于 2021-01-20T07:20:55.577 回答
0

在 lodash 你这样做:

_.pickBy(object, _.identity);
于 2018-09-03T09:09:04.203 回答
-1

虽然_.compact记录在数组中使用。它似乎也适用于对象。我刚刚在 chrome、opera 和 firefox 控制台中运行了以下命令:

var obj = {first: 1, second: null, third: 3, fourth: function(){return 5}}
undefined
_.compact(obj)

[1, 3, function()]

更新:由于示例表明调用_.compact对象将删除键并返回压缩数组。

于 2016-05-30T19:00:35.470 回答