I have a Javascript object like:
var my_object = { a:undefined, b:2, c:4, d:undefined };
How to remove all the undefined properties? False
with pure JavaScript: (although Object.entries is ES7, Object.assign is ES6; but equivalent ES5 uses Object.keys only should be also doable); also notice v != null
checks for both null and undefined;
> var d = { a:undefined, b:2, c:0, d:undefined, e: null, f: 0.3, s: "", t: false };
undefined
> Object.entries(d)
.filter(([ k, v ]) => (v != null))
.reduce((acc, [k, v]) => Object.assign(acc, {[k]: v}), {})
{ b: 2, c: 0, f: 0.3, s: '', t: false }
Edit: this below is the version with ES5 Object.keys only: but generally with ES7 in Node v8 is pretty much enjoyable ;-)
> Object.keys(d)
.filter(function(k) { return d[k] != null; })
.reduce(function(acc, k) { acc[k] = d[k]; return acc; }, {});
{ b: 2, c: 0, f: 0.3, s: '', t: false }
Update in October 2017: with Node v8 (since v8.3 or so) now it has object spreading construct:
> var d = { a:undefined, b:2, c:0, d:undefined,
e: null, f: -0.0, s: "", t: false, inf: +Infinity, nan: NaN };
undefined
> Object.entries(d)
.filter(([ k, v ]) => (v != null))
.reduce((acc, [k, v]) => ({...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }
or within one reduce only:
> Object.entries(d)
.reduce((acc, [k, v]) => (v==null ? acc : {...acc, [k]: v}), {})
{ b: 2, c: 0, f: -0, s: '', t: false, inf: Infinity, nan: NaN }
Update: someone want recursive? isn't that hard either, just need an additional check of isObject, and recursively call itself:
> function isObject(o) {
return Object.prototype.toString.call(o) === "[object Object]"; }
undefined
> function dropNullUndefined(d) {
return Object.entries(d)
.reduce((acc, [k, v]) => (
v == null ? acc :
{...acc, [k]: (isObject(v) ? dropNullUndefined(v) : v) }
), {});
}
> dropNullUndefined({a: 3, b:null})
{ a: 3 }
> dropNullUndefined({a: 3, b:null, c: { d: 0, e: undefined }})
{ a: 3, c: { d: 0 } }
my conclusion: if pure Javascript can do, I would avoid any third party library dependencies:
To omit all falsey values but keep the boolean primitives this solution helps.
_.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));
let fields = {
str: 'CAD',
numberStr: '123',
number : 123,
boolStrT: 'true',
boolStrF: 'false',
boolFalse : false,
boolTrue : true,
undef: undefined,
nul: null,
emptyStr: '',
array: [1,2,3],
emptyArr: []
};
let nobj = _.omitBy(fields, v => (_.isBoolean(v)||_.isFinite(v)) ? false : _.isEmpty(v));
console.log(nobj);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
With lodash (or underscore) You may do
var my_object = { a:undefined, b:2, c:4, d:undefined, e:null };
var passedKeys = _.reject(Object.keys(my_object), function(key){ return _.isUndefined(my_object[key]) || _.isNull(my_object[key]) })
newObject = {};
_.each(passedKeys, function(key){
newObject[key] = my_object[key];
});
Otherwise, with vanilla JavaScript, you can do
var my_object = { a:undefined, b:2, c:4, d:undefined };
var new_object = {};
Object.keys(my_object).forEach(function(key){
if (typeof my_object[key] != 'undefined' && my_object[key]!=null){
new_object[key] = my_object[key];
}
});
Not to use a falsey test, because not only "undefined" or "null" will be rejected, also is other falsey value like "false", "0", empty string, {}. Thus, just to make it simple and understandable, I opted to use explicit comparison as coded above.
Here's the lodash approach I'd take:
_(my_object)
.pairs()
.reject(function(item) {
return _.isUndefined(item[1]) ||
_.isNull(item[1]);
})
.zipObject()
.value()
The pairs() function turns the input object into an array of key/value arrays. You do this so that it's easier to use reject() to eliminate undefined
and null
values. After, you're left with pairs that weren't rejected, and these are input for zipObject(), which reconstructs your object for you.
Just:
_.omit(my_object, _.isUndefined)
The above doesn't take in account null
values, as they are missing from the original example and mentioned only in the subject, but I leave it as it is elegant and might have its uses.
Here is the complete example, less concise, but more complete.
var obj = { a: undefined, b: 2, c: 4, d: undefined, e: null, f: false, g: '', h: 0 };
console.log(_.omit(obj, function(v) { return _.isUndefined(v) || _.isNull(v); }));
Shortest way (lodash v4):
_.pickBy(my_object)