Comment supprimer les valeurs non définies et nulles d'un objet à l'aide de lodash?


173

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? Les faux attributs doivent rester.

Réponses:


195

Si vous souhaitez supprimer toutes les valeurs falsey , le moyen le plus compact est:

Pour Lodash 4.x et versions ultérieures :

_.pickBy({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

Pour l' ancien Lodash 3.x:

_.pick(obj, _.identity);

_.pick({ a: null, b: 1, c: undefined }, _.identity);
>> Object {b: 1}

63
Veuillez noter que dans lodash 4, cela devrait être_.pickBy(obj, _.identity);
Tom Spencer

30
Veuillez noter que cette méthode supprimera également les fausses valeurs.
illimité

12
Attention, cela supprimera la propriété booléenne ayant falseValu
Sai Ram

6
En plus de supprimer false, cela supprimera également les attributs avec 0 et '' comme valeur ... ce n'est pas une bonne idée.
Federico Budassi

4
Cette réponse n'est pas correcte car elle supprime également les fausses valeurs. Vérifiez ma réponse ci-dessous.
Tiago Bértolo

225

Vous pouvez simplement enchaîner _.omit()avec _.isUndefinedet _.isNullcompositions, et obtenir le résultat avec l' évaluation paresseuse.

Démo

var result = _(my_object).omit(_.isUndefined).omit(_.isNull).value();

Mise à jour du 14 mars 2016 :

Comme mentionné par les dylants dans la section des commentaires, vous devez utiliser la _.omitBy()fonction car elle utilise un prédicat au lieu d'une propriété. Vous devriez l'utiliser pour la version lodash 4.0.0et au-dessus.

DEMO

var result = _(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();

Mise à jour du 1er juin 2016 :

Comme l'a commenté Max Truxa , lodash offrait déjà une alternative _.isNil, qui vérifie à la fois nullet undefined:

var result = _.omitBy(my_object, _.isNil);

7
Ceux qui utilisent des versions plus récentes de lodash devraient utiliser la omitByfonction à la place de omit. So_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
dylants

31
Depuis lodash 4.0.0, vous pouvez utiliser _.isNilau lieu de chaîner _.isUndefinedet _.isNull. Cela le rend encore plus court:var result = _.omitBy(my_object, _.isNil);
Max Truxa

@MaxTruxa comment le modifieriez-vous pour vérifier les valeurs "Nil" de manière récursive?
aegyed

1
Lodash omitByest moins performant que pickBy, donc ce dernier doit être préféré, et la condition de la fonction iteratee inversée. La réponse acceptée ci-dessus a raison.
Ernesto

1
La question de l'OP seulement spécifiée nullet undefinedvaleurs. Le identityprédicat supprimera également des falsevaleurs, donc si vous le basez simplement sur l'intention de la question, je ne vois pas de problème avec ma réponse. De plus, si nous parlons de «performances», il omitBysuffit d'appeler pickByavec un identityprédicat annulé , par défaut. Donc, en termes de performances, c'est trop petit pour être significatif.
ryeballar

38

si vous utilisez lodash, vous pouvez utiliser _.compact(array)pour supprimer toutes les fausses valeurs d'un tableau.

_.compact([0, 1, false, 2, '', 3]);
// => [1, 2, 3]

https://lodash.com/docs/4.17.4#compact


36
compact s'applique aux tableaux mais la question concerne les objets
guidoman

1
Sauf que je veux garder 0. Argh, si proche.
Sammi

2
@Sammi, vous pouvez utiliser _.pickBy(object, _.isNumber)dans ce cas.
John Rix

1
Merci @Herick. Ça marche. Je vais aller dormir maintenant.
technophyle

1
@technophyle, je suis d'accord avec vous (et c'est moi qui ai écrit cette réponse, ha). Mais je garde cette réponse ici parce que cela résout au moins les problèmes de certaines personnes.
JavaFish

26

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 donnée ici par d'autres personnes:

_.pickBy({ a: null, b: 1, c: undefined, d: false }, _.identity);

Supprime également les falsevaleurs qui ne sont pas souhaitées ici.


{"a":1,"b":{"a":1,"b":null,"c":undefined}}, propriété object.b b, 'c' ne sera pas supprimé
mqliutie

@mqliutie comme prévu.
Tiago Bértolo

18

Juste:

_.omit(my_object, _.isUndefined)

Ce qui précède ne prend pas en compte les nullvaleurs, car elles sont absentes de l'exemple d'origine et mentionnées uniquement dans le sujet, mais je la laisse car elle est élégante 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); }));

8
Notez que c'est pour Lodash v.3. Pour la v.4, vous devez utiliser _.omitBy.
PhiLho

16

Pour compléter les autres réponses, dans lodash 4 pour ignorer uniquement indéfini et nul (et pas des propriétés comme false), vous pouvez utiliser un prédicat dans _.pickBy:

_.pickBy(obj, v !== null && v !== undefined)

Exemple ci-dessous:

const obj = { a: undefined, b: 123, c: true, d: false, e: null};

const filteredObject = _.pickBy(obj, v => v !== null && v !== undefined);

console.log = (obj) => document.write(JSON.stringify(filteredObject, null, 2));
console.log(filteredObject);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>


1
Ceci est la meilleure solution si vous ne voulez pas supprimer 0, '', les falsevaleurs. Vous pouvez également raccourcir le rappel en v => v != null.
SimpleJ

2
Solution simple. Merci pour ça.
Arjun G Perambra

10

Selon les documents de lodash:

_.compact(_.map(array, fn))

Vous pouvez également filtrer toutes les valeurs nulles


6

Pour un objet imbriqué profond, vous pouvez utiliser mon extrait de code 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
};

5

J'ai rencontré un problème similaire avec la suppression undefinedd'un objet (profondément), et j'ai trouvé que si vous êtes d'accord pour convertir votre ancien objet ordinaire et utiliser JSON, une fonction d'aide rapide et sale ressemblerait à ceci:

function stripUndefined(obj) {
  return JSON.parse(JSON.stringify(obj));
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description

"... Si indéfini, une fonction ou un symbole est rencontré lors de la conversion, il est soit omis (lorsqu'il est trouvé dans un objet), soit censuré à null (lorsqu'il est trouvé dans un tableau)."


5

avec du JavaScript pur: (bien qu'Object.entries soit ES7, Object.assign est ES6; mais l'équivalent ES5 utilise uniquement Object.keys devrait également être faisable); notez également les v != nullvérifications de null et d'indéfini;

> 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: ceci ci-dessous est 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 d'octobre 2017 : avec Node v8 (depuis la v8.3 environ), il a maintenant une construction de propagation d'objets:

> 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 seule réduction:

> 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 pas si difficile non plus, il suffit d'une vérification supplémentaire de isObject et de s'appeler récursivement:

> 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 pur peut le faire, j'éviterais toute dépendance de bibliothèque tierce:


Vous pouvez utiliser Object.fromEntries pour éviter d'utiliser réduire: Object.fromEntries (Object.entries (d) .filter (([k, v]) => (v! = Null)))
ppierre

5

Étant donné que certains d'entre vous sont peut-être arrivés à la question en cherchant à supprimer spécifiquement uniquement undefined , vous pouvez utiliser:

  • une combinaison de méthodes Lodash

    _.omitBy(object, _.isUndefined)
  • le rundefpackage, qui supprime uniquement les undefinedpropriétés

    rundef(object)

Si vous devez supprimer des propriétés de manière récursiveundefined , le rundefpackage a également une recursiveoption.

rundef(object, false, true);

Consultez la documentation pour plus de détails.


3

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 d'entrée en un tableau de tableaux clé / valeur. Vous faites cela pour qu'il soit plus facile d'utiliser rejeter () pour éliminer undefinedet nullvaloriser. Après, 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.


3

En tenant compte du fait que undefined == nullnous 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 }

Exemple JSBin


1
revisitant ceci ... je ne sais pas pourquoi mais cette fois j'ai dû utiliser _.omitBy ... json = _.omitBy (json, (it) => it == null);
danday74



1

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 JavaScript vanille, 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 un test faux, car non seulement "undefined" ou "null" sera rejeté , il y a aussi d'autres valeurs fausses comme "false", "0", chaîne vide, {}. Ainsi, juste pour le rendre simple et compréhensible, j'ai choisi d'utiliser la comparaison explicite comme codé ci-dessus.


1
ce n'est pas récursif cependant
user3743222

1

Pour omettre toutes les valeurs falsey mais conserver 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/lodash@4.17.11/lodash.min.js"></script>


0
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 }

1
_.reject traite l'entrée comme un tableau (il ne prend en compte que les valeurs, pas les clés), pas un JSON. Le newObject résultant est [2,4] et non {b: 2, c: 4}. De plus, il ne rejette pas la clé «nulle».
TaoPR

0

J'utiliserais un trait de soulignement et m'occuperais également des chaînes vides:

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 .


0

Pour les objets et les tableaux imbriqués en profondeur. et exclure les valeurs vides de la chaîne et de 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"
}


0

Pour ceux d'entre vous qui cherchent à supprimer d'un tableau d'objets et qui utilisent lodash, vous pouvez faire quelque chose comme ceci:


 const objects = [{ a: 'string', b: false, c: 'string', d: undefined }]
 const result = objects.map(({ a, b, c, d }) => _.pickBy({ a,b,c,d }, _.identity))

 // [{ a: 'string', c: 'string' }]

Remarque: vous n'avez pas à détruire si vous ne le souhaitez pas.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.