Wie entferne ich undefinierte und Nullwerte mit lodash aus einem Objekt?


172

Ich habe ein Javascript-Objekt wie:

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

Wie entferne ich alle undefinierten Eigenschaften? Falsche Attribute sollten bleiben.

Antworten:


195

Wenn Sie alle Falsey- Werte entfernen möchten , ist der kompakteste Weg:

Für Lodash 4.x und höher :

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

Für Legacy- Lodash 3.x:

_.pick(obj, _.identity);

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

63
Bitte beachten Sie, dass dies in Lodge 4 sein sollte_.pickBy(obj, _.identity);
Tom Spencer

30
Bitte beachten Sie, dass diese Methode auch falsche Werte entfernt.
unbegrenzt

12
Seien Sie vorsichtig, dies wird boolesche Eigenschaft mit falseWert entfernen
Sai Ram

6
Neben dem Entfernen von false werden auch Attribute mit 0 und '' als Wert entfernt ... keine gute Idee.
Federico Budassi

4
Diese Antwort ist nicht korrekt, da sie auch falsche Werte entfernt. Überprüfen Sie meine Antwort unten.
Tiago Bértolo

224

Sie können einfach _.omit()mit _.isUndefinedund _.isNullKompositionen verketten und das Ergebnis mit einer verzögerten Bewertung erhalten.

Demo

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

Update 14. März 2016 :

Wie von Dylants im Kommentarbereich erwähnt, sollten Sie die _.omitBy()Funktion verwenden, da sie ein Prädikat anstelle einer Eigenschaft verwendet. Sie sollten dies für die lodash-Version 4.0.0und höher verwenden.

DEMO

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

Update 1. Juni 2016 :

Wie von Max Truxa kommentiert , bot lodash bereits eine Alternative _.isNil, die sowohl prüft nullals auch undefined:

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

7
Diejenigen, die neuere Versionen von lodash verwenden, sollten die omitByFunktion anstelle von verwenden omit. So_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
dylants

31
Seit lodash 4.0.0 können Sie _.isNilanstelle von Verkettung _.isUndefinedund verwenden _.isNull. Dies macht es noch kürzer:var result = _.omitBy(my_object, _.isNil);
Max Truxa

@ MaxTruxa Wie würden Sie es ändern, um rekursiv nach "Null" -Werten zu suchen?
Uhr

1
Lodashs omitByist weniger performant als pickBy, daher sollte letzteres bevorzugt und die Bedingung in der Iteratee-Funktion umgekehrt werden. Die oben akzeptierte Antwort hat das richtig verstanden.
Ernesto

1
Die Frage des OP nur angegeben nullund undefinedWerte. Das identityPrädikat entfernt auch falseWerte. Wenn Sie es also einfach auf der Absicht der Frage basieren, sehe ich kein Problem mit meiner Antwort. Wenn es um "Leistung" geht, rufen Sie standardmäßig omitByeinfach pickBymit einem negierten identityPrädikat auf. In Bezug auf die Leistung ist es also zu klein, um signifikant zu sein.
Roggenballar

38

Wenn Sie lodash verwenden, können Sie _.compact(array)alle falschen Werte aus einem Array entfernen.

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

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


36
Kompakt gilt für Arrays, aber die Frage betrifft Objekte
Guidoman

1
Außer ich möchte 0 behalten. Argh, so nah.
Sammi

2
@Sammi, können Sie _.pickBy(object, _.isNumber)in diesem Fall verwenden.
John Rix

1
Danke @Herick. Das funktioniert. Ich werde jetzt schlafen gehen.
Technophyle

1
@technophyle, ich stimme dir zu (und ich bin derjenige, der diese Antwort geschrieben hat, ha). Aber ich halte diese Antwort hier oben, weil sie zumindest die Probleme einiger Menschen löst .
JavaFish

24

Die richtige Antwort ist:

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

Das ergibt:

{b: 1, d: false}

Die hier von anderen Leuten gegebene Alternative:

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

Entfernt auch falseWerte, die hier nicht erwünscht sind.


{"a":1,"b":{"a":1,"b":null,"c":undefined}}, object.b Eigenschaft b, 'c' wird nicht entfernt
mqliutie

@mqliutie wie erwartet.
Tiago Bértolo

17

Gerade:

_.omit(my_object, _.isUndefined)

Das Obige berücksichtigt keine nullWerte, da sie im ursprünglichen Beispiel fehlen und nur im Betreff erwähnt werden, aber ich lasse es, da es elegant ist und möglicherweise seine Verwendung hat.

Hier ist das vollständige Beispiel, weniger präzise, ​​aber vollständiger.

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

7
Beachten Sie, dass dies für Lodash v.3 gilt. Für v.4 müssen Sie verwenden _.omitBy.
PhiLho

16

Um die anderen Antworten zu vervollständigen, können Sie in lodash 4, um nur undefiniert und null (und nicht Eigenschaften wie false) zu ignorieren , ein Prädikat verwenden in _.pickBy:

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

Beispiel unten:

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
Dies ist die beste Lösung , wenn Sie nicht wollen , zu entfernen 0, '', falseWerte. Sie können den Rückruf auch auf verkürzen v => v != null.
SimpleJ

2
Einfache Lösung. Danke dafür.
Arjun G Perambra

10

Laut lodash docs:

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

Sie können auch alle Nullen herausfiltern


6

Für tief verschachtelte Objekte können Sie mein Snippet für lodash> 4 verwenden

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

Ich bin auf ein ähnliches Problem beim Entfernen undefinedvon einem Objekt (tiefgreifend) gestoßen und habe festgestellt, dass eine schnelle und schmutzige Hilfsfunktion folgendermaßen aussehen würde, wenn Sie Ihr einfaches altes Objekt konvertieren und JSON verwenden können:

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

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

"... Wenn eine undefinierte Funktion oder ein Symbol während der Konvertierung angetroffen wird, wird es entweder weggelassen (wenn es in einem Objekt gefunden wird) oder auf null zensiert (wenn es in einem Array gefunden wird)."


5

mit reinem JavaScript: (obwohl Object.entries ES7 ist, ist Object.assign ES6; aber äquivalent ES5 verwendet nur Object.keys sollte auch machbar sein); Beachten Sie auch die v != nullÜberprüfungen auf null und undefiniert.

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

Bearbeiten: Dies unten ist die Version nur mit ES5 Object.keys: aber im Allgemeinen mit ES7 in Node v8 ist ziemlich viel Spaß ;-)

> 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 im Oktober 2017 : Mit Node v8 (seit v8.3 oder so) hat es jetzt ein Objektverbreitungskonstrukt:

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

oder nur innerhalb einer reduzieren:

> 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: will jemand rekursiv? ist auch nicht so schwer, brauche nur eine zusätzliche Überprüfung von isObject und rufe sich rekursiv auf:

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

Mein Fazit: Wenn reines Javascript dies kann, würde ich jegliche Bibliotheksabhängigkeiten von Drittanbietern vermeiden:


5

Da einige von Ihnen möglicherweise zu der Frage gekommen sind, nur gezielt zu entfernen undefined, können Sie Folgendes verwenden:

  • eine Kombination von Lodash-Methoden

    _.omitBy(object, _.isUndefined)
  • das rundefPaket, das nur undefinedEigenschaften entfernt

    rundef(object)

Wenn Sie Eigenschaften rekursiv entfernen müssen undefined, verfügt das rundefPaket auch über eine recursiveOption.

rundef(object, false, true);

Weitere Informationen finden Sie in der Dokumentation .


3

Hier ist der Lodash-Ansatz, den ich wählen würde:

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

Die Funktion pair () verwandelt das Eingabeobjekt in ein Array von Schlüssel / Wert-Arrays. Sie tun dies, damit es einfacher ist, Reject () zum Eliminieren undefinedund nullWerte zu verwenden. Danach bleiben Paare übrig, die nicht abgelehnt wurden, und diese werden für zipObject () eingegeben , das Ihr Objekt für Sie rekonstruiert.


3

Unter Berücksichtigung, dass undefined == nullwir wie folgt schreiben können:

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

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

JSBin Beispiel


1
Wiederholung dieses ... nicht sicher warum, aber dieses Mal musste ich _.omitBy verwenden ... json = _.omitBy (json, (it) => it == null);
danday74



1

Mit lodash (oder Unterstrich) können Sie tun

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

Andernfalls können Sie mit Vanille-JavaScript tun

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

Verwenden Sie keinen Falsey-Test, da nicht nur "undefined" oder "null" abgelehnt wird, sondern auch andere Falsey-Werte wie "false", "0", leere Zeichenfolge, {}. Um es einfach und verständlich zu machen, habe ich mich für den expliziten Vergleich entschieden, wie oben codiert.


1
Dies ist jedoch nicht rekursiv
user3743222

1

Um alle Falsey- Werte wegzulassen , aber die booleschen Grundelemente beizubehalten , hilft diese Lösung.

_.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 behandelt Eingaben als Array (es berücksichtigt nur die Werte, keine Schlüssel), nicht als JSON. Das resultierende neue Objekt ist [2,4] nicht {b: 2, c: 4}. Außerdem wird der "Null" -Schlüssel nicht abgelehnt.
TaoPR

0

Ich würde Unterstrich verwenden und mich auch um leere Zeichenfolgen kümmern:

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

Für tief verschachtelte Objekte und Arrays. und leere Werte von String und NaN ausschließen

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)

Ergebnis:

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


0

Für diejenigen unter Ihnen, die hierher kommen, um aus einer Reihe von Objekten zu entfernen und lodash zu verwenden, können Sie Folgendes tun:


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

Hinweis: Sie müssen nicht zerstören, wenn Sie nicht möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.