Remove empty properties / falsy values from Object with Underscore.js

JavascriptArraysObjectunderscore.js

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

You could make your own underscore plugin (mixin) :

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

And then use it as a native underscore method :

var o = _.compactObject({
  foo: 'bar',
  a: 0,
  b: false,
  c: '',
  d: null,
  e: undefined
});

Update

As @AndreiNeculau pointed out, this mixin affects the original object, while the original compact underscore method returns a copy of the array.
To solve this issue and make our compactObject behave more like it's cousin, here's a minor update:

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

Solution 3 - Javascript

Quick 'n Clear: _.omitBy( source, i => !i );

This is stated in an inverse fashion to Emil's answer. This way imho reads clearer; it's more self explanatory.

Slightly less clean if you don't have the luxury of ES6: _.omitBy( source, function(i){return !i;});

Alternate: _.omitBy( source, _.isEmpty)

Using _.isEmpty, instead of _.identity for truthiness, will also conveniently remove empty arrays and objects from the collection and perhaps inconveniently remove numbers and dates. Thus the outcome is NOT an exact answer to the OP's question, however it could be useful when looking to remove empty collections.

Solution 4 - Javascript

With lodash's transform,

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

Solution 5 - Javascript

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

Solution 6 - Javascript

You can create a shallow clone:

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

Solution 7 - Javascript

for object use delete.

for(var k in obj){

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

Solution 8 - Javascript

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'
//   }
// }

Solution 9 - Javascript

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.

Solution 10 - Javascript

You should use pickBy from lodash.

The default signature of pickBy is _.(sourceObj, [_.identity]) so it will remove empty properties

_.pickBy(sourceObj);

Solution 11 - Javascript

in the lodash you do like this:

_.pickBy(object, _.identity);

Solution 12 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1082754View Question on Stackoverflow
Solution 1 - JavascriptEmil LundbergView Answer on Stackoverflow
Solution 2 - Javascriptgion_13View Answer on Stackoverflow
Solution 3 - JavascriptShwaydoggView Answer on Stackoverflow
Solution 4 - JavascriptraineView Answer on Stackoverflow
Solution 5 - JavascriptFlorian MargaineView Answer on Stackoverflow
Solution 6 - JavascriptwebwiseView Answer on Stackoverflow
Solution 7 - JavascriptAnoopView Answer on Stackoverflow
Solution 8 - JavascriptMarco GodínezView Answer on Stackoverflow
Solution 9 - JavascriptGeoff LeeView Answer on Stackoverflow
Solution 10 - JavascriptHaseeb AView Answer on Stackoverflow
Solution 11 - JavascriptHossein RezaeiView Answer on Stackoverflow
Solution 12 - JavascripttzviView Answer on Stackoverflow