Lodash kullanarak bir nesneden tanımsız ve boş değerler nasıl kaldırılır?


173

Ben gibi bir Javascript nesnesi var:

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

Tanımlanmamış tüm özellikler nasıl kaldırılır? Yanlış özellikler kalmalıdır.

Yanıtlar:


195

Tüm falsey değerlerini kaldırmak istiyorsanız en kompakt yol:

İçin daha sonra Lodash 4.x ve :

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

İçin eski Lodash 3.x:

_.pick(obj, _.identity);

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

63
Lodash 4'te bunun olması gerektiğini lütfen unutmayın_.pickBy(obj, _.identity);
Tom Spencer

30
Plaese, bu yöntemin yanlış değeri de kaldıracağını unutmayın.
sınırsız

12
Dikkatli olun, bu falsedeğerli boolean mülkü kaldıracak
Sai Ram

6
Yanlış olanı kaldırmanın yanı sıra, 0 ve '' ile nitelikleri de kaldıracaktır ... iyi bir fikir değil.
Federico Budassi

4
Yanlış yanıtı da kaldırdığından bu yanıt düzeltilmez. Cevabımı aşağıdan kontrol edin.
Tiago Bértolo

226

Basitçe ve kompozisyonlar _.omit()ile zincirleme yapabilir ve tembel değerlendirme ile sonucu elde edebilirsiniz._.isUndefined_.isNull

gösteri

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

Güncelleme 14 Mart 2016 :

Yorum bölümünde dylants tarafından belirtildiği gibi _.omitBy(), bir özellik yerine bir yüklem kullandığından işlevi kullanmalısınız . Bunu lodash sürümü 4.0.0ve üstü için kullanmalısınız .

DEMO

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

Güncelleme 1 Haziran 2016 :

Tarafından yorumladığı gibi Max Truxa , zaten bir alternatif sağlanan lodash _.isNil, hem denetler nullve undefined:

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

7
Lodash'ın daha yeni sürümlerini kullananlar omitBybunun yerine işlevi kullanmalıdır omit. Yani_(my_object).omitBy(_.isUndefined).omitBy(_.isNull).value();
dylants

31
Lodash 4.0.0 sürümünden bu yana _.isNilzincirleme _.isUndefinedve yerine kullanabilirsiniz _.isNull. Bu onu daha da kısaltır:var result = _.omitBy(my_object, _.isNil);
Max Truxa 8

@MaxTruxa "Nil" değerlerini özyinelemeli olarak kontrol etmek için nasıl değiştirirsiniz?
16:50, aegyed

1
Lodash'lar omitBydaha az performans gösterir pickBy, bu nedenle ikincisi tercih edilmelidir ve yineleme fonksiyonundaki durum tersine çevrilir. Yukarıdaki kabul edilen cevap bu doğru.
Ernesto

1
OP'nin sorusu sadece belirtildi nullve undefineddeğerler. identityYüklem da kaldıracaktır falsesadece benim cevap Sorunun niyet o zaman görmüyorum bir sorun üzerine onu temelli eğer öyleyse, değerleri. Ek olarak, "performans" hakkında konuşuyorsak , varsayılan olarak reddedilen bir yüklemle omitByçağrı yapmanız yeterlidir . Dolayısıyla, performans açısından, anlamlı olamayacak kadar küçük. pickByidentity
ryeballar

38

lodash kullanıyorsanız _.compact(array), bir dizideki tüm hatalı değerleri kaldırmak için kullanabilirsiniz .

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

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


36
kompakt diziler için geçerlidir, ancak soru nesneler hakkında
guidoman

1
Dışında 0 tutmak istiyorum. Argh, çok yakın.
Sammi

2
@Sammi, _.pickBy(object, _.isNumber)bu durumda kullanabilirsiniz .
John Rix

1
Teşekkürler @Herick. Bu işe yarıyor. Şimdi uyuyacağım.
technophyle

1
@ technophyle, sana katılıyorum (ve bu cevabı yazan kişi ben, ha). Ama bu cevabı burada tutuyorum çünkü en azından bazı insanların problemlerini çözüyor .
JavaFish

26

Doğru cevap:

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

Sonuç:

{b: 1, d: false}

Burada başkaları tarafından verilen alternatif:

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

Ayrıca falseburada istenmeyen değerleri de kaldıracaktır .


{"a":1,"b":{"a":1,"b":null,"c":undefined}}, object.b özelliği b, 'c' kaldırılmayacak
mqliutie

@mqliutie beklendiği gibi.
Tiago Bértolo

18

Sadece:

_.omit(my_object, _.isUndefined)

Yukarıdakiler null, orijinal örnekten eksik oldukları ve sadece konuya değindikleri için değerleri dikkate almaz , ancak zarif ve kullanımları olabileceği için bırakıyorum.

İşte tam örnek, daha az özlü, ama daha eksiksiz.

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
Bunun Lodash v.3 için olduğunu unutmayın. V.4 için kullanmak zorundasınız _.omitBy.
PhiLho

16

Diğer cevapları tamamlamak için, lodash 4'te yalnızca tanımsız ve null değerini yok saymak (Ve gibi özellikleri değil false) bir yüklem kullanabilirsiniz _.pickBy:

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

Aşağıdaki örnek:

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
Bu kaldırmak istemiyorsanız iyi çözümdür 0, '', falsedeğerlerini. Ayrıca için geri aramayı kısaltabilirsiniz v => v != null.
SimpleJ

2
Basit çözüm. Bunun için teşekkür ederim.
Arjun G Perambra

10

Lodash belgelerine göre:

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

Ayrıca tüm boş değerleri filtreleyebilirsiniz


6

Derin iç içe nesne için snippet'imi lodash> 4 için kullanabilirsiniz

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

Ben undefinedbir nesneden (derinden) kaldırma ile benzer bir sorunla karşılaştı ve düz eski nesneyi dönüştürmek ve JSON kullanmak için Tamam iseniz, hızlı ve kirli bir yardımcı işlevi şöyle görüneceğini bulundu:

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

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

"... Tanımlanmayan bir işlev veya dönüştürme sırasında bir sembolle karşılaşılırsa, ya atlanır (bir nesnede bulunduğunda) ya da null değerine sansürlenir (bir dizide bulunduğunda)."


5

saf JavaScript ile: (Object.entries ES7 olmasına rağmen, Object.assign ES6'dır; ancak eşdeğer ES5'te yalnızca Object.key kullanılır) da yapılabilir); ayrıca v != nullnull ve undefined için denetimlere dikkat edin ;

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

Düzenleme: Bu sadece ES5 Object.keys sürümdür: ama genellikle Düğüm v8 ES7 ile oldukça keyifli ;-)

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

Ekim 2017'de güncelleme : Düğüm v8 ile (v8.3'ten beri) şimdi nesne yayma yapısı var:

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

veya yalnızca bir indirim dahilinde:

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

Güncelleme: Birisi özyinelemek ister mi? o kadar da zor değil, ek bir isObject kontrolüne ihtiyacınız var ve kendini tekrar tekrar çağırınız:

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

benim sonuç: saf Javascript yapabilir, herhangi bir üçüncü taraf kütüphane bağımlılıkları önlemek:


Sen kullanabilirsiniz Object.fromEntries Object.fromEntries (Object.entries (d) .filter (([k, v]) => (v = null))!): Azaltmak kullanmaktan kaçınmak için
ppierre

5

Bazılarınız yalnızca özel olarak kaldırmayı isteyen soruya ulaşmış olabileceği için undefinedşunları kullanabilirsiniz:

  • Lodash yöntemlerinin bir kombinasyonu

    _.omitBy(object, _.isUndefined)
  • rundefSadece kaldırır paketi undefinedözelliklerini

    rundef(object)

Eğer gerekiyorsa yinelemeli kaldırma undefinedözellikleri, rundefpaket ayrıca sahiptir recursiveseçeneği.

rundef(object, false, true);

Daha fazla ayrıntı için belgelere bakın.


3

İşte alacağım sadakat yaklaşımı:

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

Çiftleri () işlev anahtar / değer dizilerin bir diziye giriş nesnesi döner. Bunu , ortadan kaldırmak ve değerleri reddetmek () kullanmak daha kolay olacak şekilde yaparsınız . Sonra, reddedilmeyen çiftler bırakılır ve bunlar nesnenizi sizin için yeniden yapılandıran zipObject () için girdiler .undefinednull


3

undefined == nullAşağıdaki gibi yazabileceğimizi dikkate alarak :

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

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

JSBin örneği


1
Bu tekrar ... neden emin değilim ama bu sefer _.omitBy kullanmak zorunda ... json = _.omitBy (json, (it) => it == null);
danday74



1

Lodash (veya alt çizgi) ile

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

Aksi takdirde, vanilya JavaScript ile şunları yapabilirsiniz:

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

Bir falsey testi kullanmamak, çünkü sadece "tanımsız" veya "null" reddedilmeyeceği gibi, "false", "0", boş dize, {} gibi diğer falsey değeridir. Böylece, sadece basit ve anlaşılır hale getirmek için yukarıda kodlandığı gibi açık karşılaştırmayı kullanmayı seçtim.


1
Bu yinelemeli değil
user3743222

1

Tüm falsey değerlerini atlamak, ancak mantıksal ilkelleri korumak için bu çözüm yardımcı olur.

_.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 girdiyi dizi olarak ele alır (JSON için değil, yalnızca değerleri dikkate alır, anahtarları değil). Sonuçta ortaya çıkan newObject, {b: 2, c: 4} değil [2,4]. Ayrıca, "null" anahtarını reddetmez.
TaoPR

0

Ben alt çizgi kullanmak ve boş dizeleri çok ilgilenir:

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

Derin iç içe nesne ve diziler için. ve boş değerleri dize ve NaN'den hariç tutma

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)

sonuç:

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


0

Buraya bir dizi nesneden kaldırmak isteyen ve lodash kullanarak bu şekilde bir şey yapabilirsiniz:


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

Not: Eğer istemiyorsanız yıkmak zorunda değilsiniz.


0

falseDeğerleri kaldırmak istemiyorsanız . İşte bir örnek:

obj = {
  "a": null,
  "c": undefined,
  "d": "a",
  "e": false,
  "f": true
}
_.pickBy(obj, x => x === false || x)
> {
    "d": "a",
    "e": false,
    "f": true
  }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.