J'ai un objet Javascript comme:
var my_object = { a:undefined, b:2, c:4, d:undefined };
Comment supprimer toutes les propriétés non définies?
Si vous souhaitez supprimer toutes les valeurs de falsey, la méthode la plus compacte est la suivante:
_.pick(obj, _.identity);
Par exemple (Lodash 3.x):
_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}
Pour Lodash 4.x:
_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}
Vous pouvez simplement chaîner _.omit()
avec les compositions _.isUndefined
et _.isNull
et obtenir le résultat avec une évaluation paresseuse.
var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();
Mise à jour du 14 mars 2016:
Comme mentionné par dylants dans la section commentaire, vous devez utiliser la fonction _.omitBy()
car elle utilise un prédicat au lieu d'une propriété. Vous devriez utiliser ceci pour la version lodash 4.0.0
et supérieure.
var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
Mise à jour le 1er juin 2016:
Comme commenté par Max Truxa , lodash a déjà fourni un _.isNil
alternatif.
var result = _.omitBy(my_object, _.isNil);
si vous utilisez lodash, vous pouvez utiliser _.compact(array)
pour supprimer faussement les valeurs d’un tableau.
_.compact([0, 1, false, 2, '', 3]);
// => [1, 2, 3]
Juste:
_.omit(my_object, _.isUndefined)
Ce qui précède ne prend pas en compte les valeurs null
, car celles-ci sont absentes de l'exemple d'origine et mentionnées uniquement dans le sujet, mais je le laisse comme il est élégant et pourrait avoir ses utilisations.
Voici l'exemple complet, moins concis, mais plus complet.
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); }));
Selon les documents lodash:
_.compact(_.map(array, fn))
Aussi, vous pouvez filtrer tous les NULL
Certains d’entre vous étant peut-être arrivés à la question cherchant à supprimer spécifiquement seulementundefined
, vous pouvez utiliser:
une combinaison de méthodes Lodash
_.omitBy(object, _.isUndefined)
le package rundef
qui supprime uniquement les propriétés undefined
rundef(object)
Si vous devez récursivement supprimer les propriétés undefined
, le package rundef
possède également une option recursive
.
rundef(object, false, true);
Voir le documentation pour plus de détails.
J'ai rencontré un problème similaire lors de la suppression de undefined
d'un objet (profondément) et j'ai constaté que si vous êtes prêt à convertir votre ancien objet brut et à utiliser JSON, une fonction d'assistance rapide et sale ressemblerait à ceci:
function stripUndefined(obj) {
return JSON.parse(JSON.stringify(obj));
}
"... Si elle n'est pas définie, une fonction ou un symbole est rencontré lors de la conversion, il est soit omis (lorsqu'il se trouve dans un objet), soit censuré en tant que null (lorsqu'il est trouvé dans un tableau)."
En prenant en compte que undefined == null
nous pouvons écrire comme suit:
let collection = {
a: undefined,
b: 2,
c: 4,
d: null,
}
console.log(_.omit(collection, it => it == null))
// -> { b: 2, c: 4 }
Voici l'approche lodash que je prendrais:
_(my_object)
.pairs()
.reject(function(item) {
return _.isUndefined(item[1]) ||
_.isNull(item[1]);
})
.zipObject()
.value()
La fonction pairs () transforme l'objet en entrée en un tableau de tableaux clé/valeur. Pour ce faire, il est plus facile d’utiliser -ject () d’éliminer les valeurs undefined
et null
. Ensuite, vous vous retrouvez avec des paires qui n'ont pas été rejetées, et celles-ci sont entrées pour zipObject () , qui reconstruit votre objet pour vous.
avec du code JavaScript pur: (bien que Object.entries soit ES7, Object.assign est ES6; mais l’ES5 équivalent utilise uniquement Object.keys devrait également être possible); notifiez également que v != null
vérifie les valeurs null et indéfinie;
> 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: voici ci-dessous la version avec ES5 Object.keys uniquement: mais généralement avec ES7 dans Node v8 est plutôt agréable ;-)
> 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 }
Mise à jour en octobre 2017 : avec Node v8 (depuis la v8.3 ou plus), il dispose désormais d'une structure d'étalement d'objet:
> 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 }
ou dans une réduction seulement:
> 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 }
Mise à jour: quelqu'un veut récursif? n'est-ce pas difficile non plus, il suffit juste d'une vérification supplémentaire de isObject et de s'appeler de manière récursive:
> 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 } }
ma conclusion: si javascript est pur, je voudrais éviter les dépendances de bibliothèques tierces:
Avec lodash (ou soulignement) Vous pouvez faire
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];
});
Sinon, avec Vanilla JavaScript, vous pouvez faire
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];
}
});
Ne pas utiliser de test falsey, car non seulement "undefined" ou "null" sera rejeté, il existe également une autre valeur falsey comme "false", "0", chaîne vide, {}. Ainsi, pour que tout soit simple et compréhensible, j’ai choisi d’utiliser la comparaison explicite codée ci-dessus.
La bonne réponse est:
_.omitBy({ a: null, b: 1, c: undefined, d: false }, _.isNil)
Cela se traduit par:
{b: 1, d: false}
L'alternative proposée ici par d'autres personnes:
_.pickBy({ a: null, b: 1, c: undefined, d: false }, _.identity);
Supprime également les valeurs false
qui ne sont pas souhaitées ici.
Pour omettre tous falsey values mais garder les primitives booléennes, cette solution est utile.
_.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/[email protected]/lodash.min.js"></script>
var my_object = { a:undefined, b:2, c:4, d:undefined };
var newObject = _.reject(my_collection, function(val){ return _.isUndefined(val) })
//--> newCollection = { b: 2, c: 4 }
Je voudrais utiliser le trait de soulignement et prendre soin des chaînes vides aussi:
var my_object = { a:undefined, b:2, c:4, d:undefined, k: null, p: false, s: '', z: 0 };
var result =_.omit(my_object, function(value) {
return _.isUndefined(value) || _.isNull(value) || value === '';
});
console.log(result); //Object {b: 2, c: 4, p: false, z: 0}
jsbin .
Pour les objets imbriqués et les tableaux profonds. et exclure les valeurs vides de string et NaN
function isBlank(value) {
return _.isEmpty(value) && !_.isNumber(value) || _.isNaN(value);
}
var removeObjectsWithNull = (obj) => {
return _(obj).pickBy(_.isObject)
.mapValues(removeObjectsWithNull)
.assign(_.omitBy(obj, _.isObject))
.assign(_.omitBy(obj, _.isArray))
.omitBy(_.isNil).omitBy(isBlank)
.value();
}
var obj = {
teste: undefined,
nullV: null,
x: 10,
name: 'Maria Sophia Moura',
a: null,
b: '',
c: {
a: [{
n: 'Gleidson',
i: 248
}, {
t: 'Marta'
}],
g: 'Teste',
eager: {
p: 'Palavra'
}
}
}
removeObjectsWithNull(obj)
résultat:
{
"c": {
"a": [
{
"n": "Gleidson",
"i": 248
},
{
"t": "Marta"
}
],
"g": "Teste",
"eager": {
"p": "Palavra"
}
},
"x": 10,
"name": "Maria Sophia Moura"
}
Pour les objets imbriqués profonds, vous pouvez utiliser mon extrait pour lodash> 4
const removeObjectsWithNull = (obj) => {
return _(obj)
.pickBy(_.isObject) // get only objects
.mapValues(removeObjectsWithNull) // call only for values as objects
.assign(_.omitBy(obj, _.isObject)) // save back result that is not object
.omitBy(_.isNil) // remove null and undefined from object
.value(); // get value
};