Filtering object properties based on value

2019-04-04 18:13发布

问题:

Is there some elegant way of filtering out falsey properties from this object with lodash/underscore? Similar to how _.compact(array) removes falsey elements from arrays

so from

{
  propA: true,
  propB: true,
  propC: false,
  propD: true,
}

returning

{
  propA: true,
  propB: true,
  propD: true,
}

回答1:

Prior to Lodash 4.0

You want _.pick, it takes a function as an argument and returns an object only containing the keys for which that function returns truthy. So you can do:

filtered = _.pick(obj, function(value, key) {return value;})

Or even more succinctly:

filtered = _.pick(obj, _.identity)

Lodash 4.0

Lodash 4.0 split the _.pick function into _.pick, which takes an array of properties, and _.pickBy which takes a function. So now it'd be

filtered = _.pickBy(obj, function(value, key) {return value;})

Or, since _.pickBy defaults to using _.identity as it's second argument, it can just be written as:

filtered = _.pickBy(obj);


回答2:

Here are two vanilla javascript options:

A.: Iterate over the object's keys and delete those having a falsey value.

var obj = {
  propA: true,
  propB: true,
  propC: false,
  propD: true,
};

Object.keys(obj).forEach(key => {
  if (!obj[key]) delete obj[key];
});

console.log(obj);

See Object.keys() and Array.prototype.forEach()

B.: Iterate over the object's keys and add truthy values to a new object.

var obj = {
  propA: true,
  propB: true,
  propC: false,
  propD: true,
};

var filteredObj = Object.keys(obj).reduce((p, c) => {    
  if (obj[c]) p[c] = obj[c];
  return p;
}, {});

console.log(filteredObj);

See Object.keys() and Array.prototype.reduce()



回答3:

If you're using lodash, I'd recommend something like this:

var object = {
    propA: true,
    propB: true,
    propC: false,
    propD: true,
};

_.pick(object, _.identity);
// →
// {
//   propA: true,
//   propB: true,
//   propD: true
// }

The pick() function generates a new object that includes properties that the callback returns truthy for. So we can just use the identity() function as the callback, since it'll just return each property value.



回答4:

Unfortunately I cannot direclty comment on the posts above yet, so I create this extra post.

Since Lodash v4 the functionality described above has been moved to _.pickBy. With _.identity as default you could also change your code to:

var filtered = _.pickBy(obj);

See this JSBin for a working example.