使用Underscore.js从Object中删除空属性/ falsy值

时间:2012-12-27 16:53:09

标签: javascript arrays object underscore.js

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

这可以通过数组上的compact来实现,但对象呢?

12 个答案:

答案 0 :(得分:166)

自Underscore版本1.7.0起,您可以使用_.pick

_.pick(sourceObj, _.identity)

说明

_.pick的第二个参数可以是用于选择值的谓词函数。将选择谓词返回 truthy 的值,并忽略谓词返回 falsy 的值。

  

选择 _.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,但它不接受谓词函数而不是白名单。

答案 1 :(得分:47)

你可以制作自己的下划线插件(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表现得更像 cousin ,这是一个小小的更新:

_.mixin({
  compactObject : function(o) {
     var clone = _.clone(o);
     _.each(clone, function(v, k) {
       if(!v) {
         delete clone[k];
       }
     });
     return clone;
  }
});

答案 2 :(得分:43)

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

这与Emil的答案相反。这样imho读得更清楚;它更加自我解释。

如果你没有ES6的奢侈品,那就不那么干净了:_.omit( source, function(i){return !i;});

替代:_.omit( source, _.isEmpty)

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

答案 3 :(得分:21)

使用lodash' transform

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});

答案 4 :(得分:17)

Object.keys(o).forEach(function(k) {
    if (!o[k]) {
        delete o[k];
    }
});

答案 5 :(得分:9)

您可以创建一个浅层克隆:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});

答案 6 :(得分:5)

用于对象使用删除。

for(var k in obj){

  if(obj.hasOwnProperty(k) && !obj[k]){
    delete obj[k];
  }
}

答案 7 :(得分:4)

突然间,我需要创建一个函数来删除递归的错误。我希望这有帮助。我正在使用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'
//   }
// }

答案 8 :(得分: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而不是falsey,这将删除将false作为值的键值对。

答案 9 :(得分:1)

您应该使用 lodash 中的 pickBy

pickBy 的默认签名是 _.(sourceObj, [_.identity]) 因此它将删除空属性

_.pickBy(sourceObj);

答案 10 :(得分:0)

在lodash中,您会这样:

_.pickBy(object, _.identity);

答案 11 :(得分:-1)

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

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

[1, 3, function()]

更新:如示例所示,对象上的调用_.compact将删除键并返回压缩数组。