objetos - Eliminar atributos en blanco de un objeto en Javascript
recorrer array de objetos javascript (24)
¿Cómo elimino todos los atributos que son undefined
o null
en un objeto JavaScript?
(La pregunta es similar a esta para Arrays)
Con Lodash:
_.omitBy({a: 1, b: null}, (v) => !v)
Debajo de la solución se eliminan empty object
null
y empty object
El empty object
o {}
es un residuo debido a una limpieza null
Para limpiar un objeto usa el siguiente
/**
* Delete all null (or undefined) properties from an object.
* Set ''recurse'' to true if you also want to delete properties in nested objects.
*/
function delete_null_properties(test, recurse) {
for (var i in test) {
if (test[i] === null || test[i] === undefined) {
delete test[i];
}
// recurse for array and object
else if (recurse && typeof test[i] === ''object'') {
test[i] = delete_null_properties(test[i], recurse);
}
if((test[i] && typeof(test[i]) === ''object'') &&
(Object.keys(test[i]).length === 0 || test[i] == [{}])) {
// delete the child property if its empty
delete test[i]
}
if(test == {}){
// delete empty ''parent'' object when there is a residue due to deletion
// of its child properties
delete test
} else if(test instanceof Array && test[i] == undefined) {
// in the case of array removed null childs by splicing it off
test.splice(i,1)
// however if the parent array itself goes empty remove it off
if(test instanceof Array && test.length == 0) {
test = null
}
}
}
return test
}
delete_null_properties(obj, true)
En lugar de eliminar la propiedad, también puede crear un nuevo objeto con las claves que no son nulas.
const removeEmpty = (obj) => {
return Object.keys(obj).filter(key => obj[key]).reduce(
(newObj, key) => {
newObj[key] = obj[key]
return newObj
}, {}
)
}
Esta función puede limpiar el objeto vacío después de eliminar los vacíos invidivales dentro del objeto o matriz. esto garantiza que no tenga un conjunto u objeto vacío.
function removeNullsInObject(obj) {
if( typeof obj === ''string'' || obj === "" ){
return;
}
$.each(obj, function(key, value){
if (value === "" || value === null){
delete obj[key];
} else if ($.isArray(value)) {
if( value.length === 0 ){
delete obj[key];
return;
}
$.each(value, function (k,v) {
removeNullsInObject(v);
});
if( value.length === 0 ){
delete obj[key];
}
} else if (typeof value === ''object'') {
if( Object.keys(value).length === 0 ){
delete obj[key];
return;
}
removeNullsInObject(value);
if( Object.keys(value).length === 0 ){
delete obj[key];
}
}
});
}
Existe una manera fácil de ejecutar esta tarea. Esto lo logra usando el método jQuery $.grep
.
var test = {
a: null,
b: ''hello world'',
c: 12345
}
var newTest = $.grep(
test,
function(element, index) {
return (test[element] && test[element] != null);
}
);
// newTest = { b: ''hello world'', c: 12345 }
$.grep
encuentra los elementos de una matriz que satisfacen una función de filtro. En este caso, cualquier atributo que no sea nulo
JSON.stringify elimina las claves indefinidas.
removeUndefined = function(json){
return JSON.parse(JSON.stringify(json))
}
La solución Lodash más simple posible para devolver un objeto con los valores null
e undefined
filtrados.
_.omitBy(obj, _.isNil)
Para cargar la respuesta de Ben sobre cómo resolver este problema usando _.pickBy de _.pickBy
, también puede resolver este problema en la biblioteca hermana: _.pick
Underscore.js .
var obj = {name: ''John'', age: null};
var compacted = _.pick(obj, function(value) {
return value !== null && value !== undefined;
});
Ver: Ejemplo JSFiddle
Para una búsqueda profunda usé el siguiente código, tal vez sea útil para cualquiera que mire esta pregunta (no se puede usar para dependencias cíclicas):
function removeEmptyValues(obj) {
for (var propName in obj) {
if (!obj[propName] || obj[propName].length === 0) {
delete obj[propName];
} else if (typeof obj === ''object'') {
removeEmptyValues(obj[propName]);
}
}
return obj;
}
Probablemente estés buscando la palabra clave delete
.
var obj = { };
obj.theProperty = 1;
delete obj.theProperty;
Puede recorrer el objeto:
var test = {
test1 : null,
test2 : ''somestring'',
test3 : 3,
}
function clean(obj) {
for (var propName in obj) {
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
clean(test);
Si le preocupa que esta eliminación de propiedad no ejecute la cadena de proptype del objeto, también puede:
function clean(obj) {
var propNames = Object.getOwnPropertyNames(obj);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
}
Algunas notas sobre null vs undefined:
test.test1 === null; // true
test.test1 == null; // true
test.notaprop === null; // false
test.notaprop == null; // true
test.notaprop === undefined; // true
test.notaprop == undefined; // true
Puede usar este componente de limpieza de objeto para limpiar todas las propiedades de falsy de un objeto y devolver un nuevo objeto sin ellas.
Ejemplos:
new cleaned object
clean({ foo: null, bar: ''foo'' }) // => { bar: ''foo'' }
Puede usar una combinación de JSON.stringify
, su parámetro JSON.parse
y JSON.parse
para volver a convertirlo en un objeto. El uso de este método también significa que el reemplazo se realiza a todas las claves anidadas dentro de los objetos anidados.
Objeto de ejemplo
var exampleObject = {
string: ''value'',
emptyString: '''',
integer: 0,
nullValue: null,
array: [1, 2, 3],
object: {
string: ''value'',
emptyString: '''',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
arrayOfObjects: [
{
string: ''value'',
emptyString: '''',
integer: 0,
nullValue: null,
array: [1, 2, 3]
},
{
string: ''value'',
emptyString: '''',
integer: 0,
nullValue: null,
array: [1, 2, 3]
}
]
};
Función de reemplazo
function replaceUndefinedOrNull(key, value) {
if (value === null || value === undefined) {
return undefined;
}
return value;
}
Limpia el objeto
exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);
Si alguien necesita eliminar valores undefined
de un objeto con una búsqueda profunda usando lodash
, aquí está el código que estoy usando. Es bastante simple modificarlo para eliminar todos los valores vacíos ( null
/ undefined
).
function omitUndefinedDeep(obj) {
return _.reduce(obj, function(result, value, key) {
if (_.isObject(value)) {
result[key] = omitUndefinedDeep(value);
}
else if (!_.isUndefined(value)) {
result[key] = value;
}
return result;
}, {});
}
Si alguien necesita una versión recursiva de la respuesta de Owen (y de Eric), aquí está:
/**
* Delete all null (or undefined) properties from an object.
* Set ''recurse'' to true if you also want to delete properties in nested objects.
*/
function delete_null_properties(test, recurse) {
for (var i in test) {
if (test[i] === null) {
delete test[i];
} else if (recurse && typeof test[i] === ''object'') {
delete_null_properties(test[i], recurse);
}
}
}
Si está usando lodash o underscore.js, aquí hay una solución simple:
var obj = {name: ''John'', age: null};
var compacted = _.pickBy(obj);
Esto solo funcionará con lodash 4, pre lodash 4 o underscore.js, use _.pick(obj, _.identity)
;
Si no quiere mutar en su lugar, pero devuelve un clon con el nulo / indefinido eliminado, puede utilizar la función de reducción de ES6.
// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
// Protect against null/undefined object passed in
return Object.keys(obj || {}).reduce((x, k) => {
// Check for null or undefined
if (obj[k] != null) {
x[k] = obj[k];
}
return x;
}, {});
}
Si quieres 4 líneas de una solución pura de ES7:
const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
if (typeof v === ''boolean'' || v) o[k] = clean(v);
return o;
}, e instanceof Array ? [] : {}) : e;
O si prefiere una versión más legible:
function filterEmpty(obj, [key, val]) {
if (typeof val === ''boolean'' || val) {
obj[key] = clean(val)
};
return obj;
}
function clean(entry) {
if (entry instanceof Object) {
const type = entry instanceof Array ? [] : {};
const entries = Object.entries(entry);
return entries.reduce(filterEmpty, type);
}
return entry;
}
Esto preservará los valores booleanos y también limpiará las matrices. También conserva el objeto original devolviendo una copia limpia.
Si usa eslint y desea evitar el disparo de la regla no-param-reasignación, puede usar Object.assign junto con .reduce y un nombre de propiedad calculado para una solución ES6 bastante elegante:
const queryParams = { a: ''a'', b: ''b'', c: ''c'', d: undefined, e: null, f: '''', g: 0 };
const cleanParams = Object.keys(queryParams)
.filter(key => queryParams[key] != null)
.reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: ''a'', b: ''b'', c: ''c'', f: '''', g: 0 }
Solución pura ES6 más corta, conviértala en una matriz, usa la función de filtro y conviértela de nuevo en un objeto. También sería fácil hacer una función ...
Por cierto. con this .length > 0
compruebo si hay un string / array vacío, por lo que eliminará las claves vacías.
const MY_OBJECT = { f: ''te'', a: [] }
Object.keys(MY_OBJECT)
.filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
.reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});
Tengo el mismo escenario en mi proyecto y logré usar el siguiente método.
Funciona con todos los tipos de datos, pocos de los mencionados anteriormente no funcionan con la fecha y las matrices vacías.
removeEmptyKeysFromObject.js
removeEmptyKeysFromObject(obj) {
Object.keys(obj).forEach(key => {
if (Object.prototype.toString.call(obj[key]) === ''[object Date]'' && obj[key].toString().length === 0) {
delete obj[key];
} else if (obj[key] && typeof obj[key] === ''object'') {
this.removeEmptyKeysFromObject(obj[key]);
} else if (obj[key] == null || obj[key] === "") {
delete obj[key];
}
if (obj[key] && typeof obj[key] === ''object'' && Object.keys(obj[key]).length === 0 && Object.prototype.toString.call(obj[key]) !== ''[object Date]'') {
delete obj[key];
}
});
return obj;
}
pasar cualquier objeto a esta función removeEmptyKeysFromObject ()
Usando ramda#pickBy :
const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)
Usando algo de ES6 / ES2015 :
1) Un simple trazador de líneas para quitar los artículos en línea sin asignación:
Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);
2) Este ejemplo fue eliminado ...
3) Primer ejemplo escrito como una función:
const removeEmpty = (obj) => {
Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]);
}
4) Esta función usa recursión para eliminar elementos de objetos anidados también:
const removeEmpty = (obj) => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === ''object'') removeEmpty(obj[key]);
else if (obj[key] == null) delete obj[key];
});
};
4b) Esto es similar a 4), pero en lugar de mutar el objeto fuente directamente, devuelve un nuevo objeto.
const removeEmpty = (obj) => {
const o = JSON.parse(JSON.stringify(obj)); // Clone source oect.
Object.keys(o).forEach(key => {
if (o[key] && typeof o[key] === ''object'')
o[key] = removeEmpty(o[key]); // Recurse.
else if (o[key] === undefined || o[key] === null)
delete o[key]; // Delete undefined and null.
else
o[key] = o[key]; // Copy value.
});
return o; // Return new object.
};
5) Un acercamiento funcional a 4b) basado en la respuesta de @ MichaelJ.Zoidl usando filter()
y reduce()
. Este también devuelve un nuevo objeto:
const removeEmpty = (obj) =>
Object.keys(obj)
.filter(k => obj[k] !== null && obj[k] !== undefined) // Remove undef. and null.
.reduce((newObj, k) =>
typeof obj[k] === ''object'' ?
Object.assign(newObj, {[k]: removeEmpty(obj[k])}) : // Recurse.
Object.assign(newObj, {[k]: obj[k]}), // Copy value.
{});
6) Igual que 4) pero con ES7 / 2016 Object.entries()
.
const removeEmpty = (obj) =>
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val === ''object'') removeEmpty(val)
else if (val == null) delete obj[key]
})
7) Igual que 4) pero en ES5 simple:
function removeEmpty(obj) {
Object.keys(obj).forEach(function(key) {
if (obj[key] && typeof obj[key] === ''object'') removeEmpty(obj[key])
else if (obj[key] == null) delete obj[key]
});
};
puedes hacer más corto con !
condición
var r = {a: null, b: undefined, c:1};
for(var k in r)
if(!r[k]) delete r[k];
Recuerde en el uso: como @semicolor anunciar en comentarios: Esto también eliminaría las propiedades si el valor es una cadena vacía, falso o cero