Come rimuovere valori non definiti e null da un oggetto usando lodash?


172

Ho un oggetto Javascript come:

var my_object = { a:undefined, b:2, c:4, d:undefined };

Come rimuovere tutte le proprietà non definite? I falsi attributi dovrebbero rimanere.

Risposte:


195

Se si desidera rimuovere tutti i valori di falso , il modo più compatto è:

Per Lodash 4.xe versioni successive :

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

Per la versione precedente di Lodash 3.x:

_.pick(obj, _.identity);

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

63
Si noti che nel lodash 4 questo dovrebbe essere_.pickBy(obj, _.identity);
Tom Spencer,

30
Si noti che questo metodo rimuoverà anche il valore falso.
illimitato

12
Attenzione, questo sarà rimuovere booleana proprietà avendo falsevalu
Sai Ram

6
Oltre a rimuovere false, rimuoverà anche gli attributi con 0 e "" come valore ... non è una buona idea.
Federico Budassi,

4
Questa risposta non è corretta poiché rimuove anche i valori falsi. Controlla la mia risposta qui sotto.
Tiago Bértolo,

225

Si può semplicemente concatenare _.omit()con _.isUndefinede _.isNullcomposizioni, e ottenere il risultato con valutazione pigra.

dimostrazione

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

Aggiornamento 14 marzo 2016 :

Come indicato dai dylants nella sezione commenti, è necessario utilizzare la _.omitBy()funzione poiché utilizza un predicato anziché una proprietà. Dovresti usarlo per la versione lodash 4.0.0e successive.

DEMO

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

Aggiornamento 1 giugno 2016 :

Come commentato da Max Truxa , lodash ha già fornito un'alternativa _.isNil, che controlla sia nulle che undefined:

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

7
Quelli che usano versioni più recenti di lodash dovrebbero usare la omitByfunzione invece di omit. Quindi_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
dylants il

31
Da lodash 4.0.0 puoi usare _.isNilinvece di concatenare _.isUndefinede _.isNull. Questo lo rende ancora più breve:var result = _.omitBy(my_object, _.isNil);
Max Truxa,

@MaxTruxa come lo modifichereste per verificare ricorsivamente i valori "Nil"?
consegnato il

1
Lodash omitByè meno performante di pickBy, quindi quest'ultimo dovrebbe essere preferito, e la condizione nella funzione iterata è invertita. La risposta accettata sopra ha capito bene.
Ernesto,

1
Solo la domanda del PO ha specificato nulle undefinedvalori. Il identitypredicato rimuoverà anche i falsevalori, quindi se semplicemente lo si basa sull'intento della domanda, allora non vedo un problema con la mia risposta. Inoltre, se ci occupiamo di "prestazioni" , per impostazione predefinita omitBychiama semplicemente pickBycon un identitypredicato negato . Quindi, in termini di prestazioni, è troppo piccolo per essere significativo.
ryeballar,

38

se si utilizza lodash, è possibile utilizzare _.compact(array)per rimuovere tutti i valori erroneamente da un array.

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

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


36
compact si applica alle matrici ma la domanda riguarda gli oggetti
guidoman

1
Tranne che voglio mantenere 0. Argh, così vicino.
Sammi,

2
@Sammi, puoi usarlo _.pickBy(object, _.isNumber)in quel caso.
John Rix,

1
Grazie @Herick. Che funzioni. Vado a dormire adesso.
tecnophyle

1
@technophyle, sono d'accordo con te (e sono io quello che ha scritto questa risposta, ah). Ma sto mantenendo questa risposta qui perché, almeno, risolve i problemi di alcune persone.
JavaFish,

25

La risposta corretta è:

_.omitBy({ a: null, b: 1, c: undefined, d: false }, _.isNil)

Ciò si traduce in:

{b: 1, d: false}

L'alternativa qui fornita da altre persone:

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

Rimuoverà anche i falsevalori che non sono desiderati qui.


{"a":1,"b":{"a":1,"b":null,"c":undefined}}, proprietà object.b b, 'c' non verrà rimosso
mqliutie il

@mqliutie come previsto.
Tiago Bértolo,

18

Appena:

_.omit(my_object, _.isUndefined)

Quanto sopra non tiene conto dei nullvalori, in quanto mancano nell'esempio originale e menzionati solo nell'argomento, ma lo lascio perché è elegante e potrebbe avere i suoi usi.

Ecco l'esempio completo, meno conciso, ma più completo.

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
Si noti che questo è per Lodash v.3. Per la v.4, devi usare _.omitBy.
PhiLho,

16

Per completare le altre risposte, in lodash 4 per ignorare solo undefined e null (E non proprietà come false) puoi usare un predicato in _.pickBy:

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

Esempio sotto:

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
Questa è la soluzione migliore se non si desidera rimuovere 0, '', falsevalori. Inoltre è possibile abbreviare la richiamata a v => v != null.
SimpleJ,

2
Soluzione semplice. Grazie per questo.
Arjun G Perambra,

10

Secondo i documenti lodash:

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

Inoltre puoi filtrare tutti i null


6

Per oggetti nidificati in profondità puoi usare il mio frammento per 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

Ho riscontrato un problema simile con la rimozione undefinedda un oggetto (in profondità) e ho scoperto che se stai bene convertire il tuo vecchio oggetto semplice e utilizzare JSON, una funzione di supporto rapida e sporca sarebbe simile a questa:

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

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

"... Se non definito, viene rilevata una funzione o un simbolo durante la conversione o viene omesso (quando viene trovato in un oggetto) o censurato su null (quando viene trovato in un array)."


5

con JavaScript puro: (sebbene Object.entries sia ES7, Object.assign è ES6; ma l'equivalente ES5 utilizza solo Object.keys dovrebbe essere fattibile); notare anche v != nullcontrolli sia nulli che indefiniti;

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

Modifica: questa sotto è la versione solo con ES5 Object.keys: ma generalmente con ES7 nel Nodo v8 è praticamente divertente ;-)

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

Aggiornamento a ottobre 2017 : con il nodo v8 (dalla v8.3 in poi) ora ha il costrutto di diffusione degli oggetti:

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

o entro una sola riduzione:

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

Aggiornamento: qualcuno vuole ricorsivo? non è poi così difficile, basta solo un controllo aggiuntivo di isObject e chiamarsi in modo ricorsivo:

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

la mia conclusione: se Javascript puro può fare, eviterei qualsiasi dipendenza da libreria di terze parti:


È possibile utilizzare Object.fromEntries per evitare l'uso di reduce: Object.fromEntries (Object.entries (d) .filter (([k, v]) => (v! = Null)))
ppierre

5

Poiché alcuni di voi potrebbero essere arrivati ​​alla domanda cercando di rimuovere solo in modo specifico undefined, è possibile utilizzare:

  • una combinazione di metodi Lodash

    _.omitBy(object, _.isUndefined)
  • il rundefpacchetto, che rimuove solo le undefinedproprietà

    rundef(object)

Se è necessario rimuovere ricorsivamente leundefined proprietà, il rundefpacchetto ha anche recursiveun'opzione.

rundef(object, false, true);

Vedi la documentazione per maggiori dettagli.


3

Ecco l'approccio lodash che prenderei:

_(my_object)
    .pairs()
    .reject(function(item) {
        return _.isUndefined(item[1]) ||
            _.isNull(item[1]);
    })
    .zipObject()
    .value()

La funzione Pair () trasforma l'oggetto di input in un array di array chiave / valore. Puoi farlo in modo che sia più facile usare reject () per eliminare undefinede nullvalori. Dopo, rimani con coppie che non sono state rifiutate, e queste sono input per zipObject () , che ricostruisce il tuo oggetto per te.


3

Tenendo conto che undefined == nullpossiamo scrivere come segue:

let collection = {
  a: undefined,
  b: 2,
  c: 4,
  d: null,
}

console.log(_.omit(collection, it => it == null))
// -> { b: 2, c: 4 }

Esempio di JSBin


1
rivisitando questo ... non so perché ma questa volta ho dovuto usare _.omitBy ... json = _.omitBy (json, (it) => it == null);
danday74,



1

Con lodash (o trattino basso) Puoi farlo

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];
});

Altrimenti, con JavaScript vaniglia, puoi farlo

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];
    }
});

Non usare un test di falsità, perché non solo "undefined" o "null" verranno rifiutati , ma anche un altro valore di falsey come "false", "0", stringa vuota, {}. Quindi, solo per renderlo semplice e comprensibile, ho scelto di usare il confronto esplicito come sopra indicato.


1
questo non è però ricorsivo
user3743222

1

Per omettere tutti i valori di falsità ma mantenere i primitivi booleani questa soluzione aiuta.

_.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 considera l'input come array (tiene conto solo dei valori, non delle chiavi), non di un JSON. Il nuovo oggetto risultante è [2,4] non {b: 2, c: 4}. Inoltre, non rifiuta la chiave "null".
TaoPR,

0

Userei il trattino basso e mi occuperei anche delle stringhe vuote:

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

Per oggetti e matrici nidificati in profondità. ed escludi valori vuoti da string e 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)

risultato:

{
   "c": {
      "a": [
         {
            "n": "Gleidson",
            "i": 248
         },
         {
            "t": "Marta"
         }
      ],
      "g": "Teste",
      "eager": {
         "p": "Palavra"
      }
   },
   "x": 10,
   "name": "Maria Sophia Moura"
}


0

Per quelli di voi che arrivano qui cercando di rimuovere da una matrice di oggetti e usando lodash è possibile fare qualcosa del genere:


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

Nota: non è necessario distruggere se non si desidera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.