Remove empty properties / falsy values from Object

2019-01-30 01:31发布

I have an object with several properties. I would like to remove any properties that have falsy values.

This can be achieved with compact on arrays, but what about objects?

11条回答
Anthone
2楼-- · 2019-01-30 01:37

You can create a shallow clone:

_(obj).reduce(function(a,v,k){ 
     if(v){ a[k]=v; } 
     return a; 
},{});
查看更多
虎瘦雄心在
3楼-- · 2019-01-30 01:38

With lodash's transform,

_.transform(obj, function(res, v, k) {
  if (v) res[k] = v;
});
查看更多
Bombasti
4楼-- · 2019-01-30 01:44

To add to gion_13's answer:

_.mixin({
  compactObject : function(o) {
     var newObject = {};
     _.each(o, function(v, k) {
       if(v !== null && v !== undefined) {
         newObject[k] = v
       }
     });
     return newObject;
  }
});

This one creates a new object and adds keys and values instead of cloning everything and deleting key-value pairs. Minor difference.

But more importantly, checks explicitly for null and undefined instead of falsey, which will delete key-value pairs that have false as a value.

查看更多
Anthone
5楼-- · 2019-01-30 01:47

Since Underscore version 1.7.0, you can use _.pick:

_.pick(sourceObj, _.identity)

Explanation

The second parameter to _.pick can be a predicate function for selecting values. Values for which the predicate returns truthy are picked, and values for which the predicate returns falsy are ignored.

pick _.pick(object, *keys)

Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys). Alternatively accepts a predicate indicating which keys to pick.

_.identity is a helper function that returns its first argument, which means it also works as a predicate function that selects truthy values and rejects falsy ones. The Underscore library also comes with a bunch of other predicates, for instance _.pick(sourceObj, _.isBoolean) would retain only boolean properties.

If you use this technique a lot, you might want to make it a bit more expressive:

var pickNonfalsy = _.partial(_.pick, _, _.identity); // Place this in a library module or something
pickNonfalsy(sourceObj);

Underscore version 1.6.0 provided _.pick as well, but it didn't accept a predicate function instead of a whitelist.

查看更多
趁早两清
6楼-- · 2019-01-30 01:54

Suddenly I needed create a function to remove recursively falsies. I hope this helps. I'm using 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 });

Then you can use it:

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'
//   }
// }
查看更多
smile是对你的礼貌
7楼-- · 2019-01-30 01:54

Although _.compact is documented for use in arrays. It seems to work for objects too. I just ran the following in chrome, opera and firefox consoles:

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

[1, 3, function()]

UPDATE: As the sample indicates calling _.compact on an object will drop the keys and return a compacted array.

查看更多
登录 后发表回答