Javascript'teki bir nesneden boş nitelikleri kaldırma


267

Bir JavaScript nesnesindeki undefinedveya nullbir JavaScript nesnesindeki tüm öznitelikleri nasıl kaldırabilirim ?

(Soru benzer bu bir Diziler için)


20
İnsanların en üst sıralara aldırmamalarını ve buradaki ES6 / ES7 sürümlerine geçmelerini şiddetle tavsiye ederiz, stackoverflow.com/a/38340730/124486
Evan Carroll

2
Ayrıca nesneyi mutasyon geçirmeyen bir gömlek ES6 burada: stackoverflow.com/a/57625661/1602301
tavuklar

Yanıtlar:


184

Nesne üzerinde döngü yapabilirsiniz:

var test = {
    test1 : null,
    test2 : 'somestring',
    test3 : 3,
}

function clean(obj) {
  for (var propName in obj) { 
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

clean(test);

Bu mülk kaldırma işleminin nesnenin prototip zincirini çalıştırmadığından endişe ediyorsanız, şunları da yapabilirsiniz:

function clean(obj) {
  var propNames = Object.getOwnPropertyNames(obj);
  for (var i = 0; i < propNames.length; i++) {
    var propName = propNames[i];
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

Null ve undefined hakkında birkaç not:

test.test1 === null; // true
test.test1 == null; // true

test.notaprop === null; // false
test.notaprop == null; // true

test.notaprop === undefined; // true
test.notaprop == undefined; // true

2
Hızlı bir düzeltme eklendi. Bu snippet bir işlevde kullanılmış olsaydı, bildirilmemiş "i" değişkeni dış kapsama sızar.
Eric Nguyen

4
(test [i] === null || test [i] === undefined) ile (test [i] == null)
jaf0

Merhaba, @EricNguyen, C ve diğer birkaç dilden farklı olarak, javascript değişkenler için blok kapsamına sahip değildir (sadece fonksiyon kapsamı), bu nedenle, i değişkeni her zaman for bloğundan sonra kapsama sızacaktır .
Gerardo Lima

1
@GerardoLima, evet. Tüm bunların bir işleve sarılı olacağını varsayıyordum. Ne (bu her bir işlevle sarılmış olduğunu varsayarak) demek sen var beyanı ihtiyaç ya olmasıdır i bile dışarıda fonksiyon kapsamı sızdırıyor.
Eric Nguyen

Bu aynı zamanda ilkel nesnenin prototipinde de dönecektir - ki bu çoğu durumda istenmez. stackoverflow.com/a/2869372/1612318
Rotareti

430

Bazı ES6 / ES2015 kullanma :

1) Öğeleri atamadan satır içi kaldırmak için basit bir astar :

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);

jsbin

2) Bu örnek kaldırıldı ...

3) Fonksiyon olarak yazılan ilk örnek:

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => obj[key] == null && delete obj[key]);
};

jsbin

4) Bu işlev , iç içe nesnelerden de öğeleri silmek için özyineleme kullanır :

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") removeEmpty(obj[key]); // recurse
    else if (obj[key] == null) delete obj[key]; // delete
  });
};

jsbin

4b) Bu 4'e benzer), ancak kaynak nesneyi doğrudan değiştirmek yerine yeni bir nesne döndürür.

const removeEmpty = obj => {
  const newObj = {};

  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") {
      newObj[key] = removeEmpty(obj[key]); // recurse
    } else if (obj[key] != null) {
      newObj[key] = obj[key]; // copy value
    }
  });

  return newObj;
};

5) 4b'ye işlevsel bir yaklaşım) @ MichaelJ.Zoidl'infilter() ve kullanarak cevabına dayanır reduce(). Bu da yeni bir nesne döndürür:

const removeEmpty = obj =>
  Object.keys(obj)
    .filter(k => obj[k] != null) // Remove undef. and null.
    .reduce(
      (newObj, k) =>
        typeof obj[k] === "object"
          ? { ...newObj, [k]: removeEmpty(obj[k]) } // Recurse.
          : { ...newObj, [k]: obj[k] }, // Copy value.
      {}
    );

jsbin

6) 4 ile aynı) ancak ES7 / 2016 ile Object.entries() .

const removeEmpty = (obj) => 
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') removeEmpty(val)
    else if (val == null) delete obj[key]
})

5b) Özyineleme kullanan ve ES2019 ile yeni bir nesne döndüren başka bir işlevsel sürüm : Object.fromEntries()

const removeEmpty = obj =>
  Object.fromEntries(
    Object.entries(obj)
      .filter(([k, v]) => v != null)
      .map(([k, v]) => (typeof v === "object" ? [k, removeEmpty(v)] : [k, v]))
  );

7) 4 ile aynı) ancak düz ES5'te :

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
    else if (obj[key] == null) delete obj[key]
  });
};

jsbin


3
@AugustinRiedinger Bir satır sonu ve bir kısaltma arasında karar vermem gerektiğinde, kısaltmanın daha az kötülük olduğunu düşünürsem bazen kısaltmaya giderim. 5) 'deki kodun akla gelmesi zor değildir ve bu, a'dan boş keysolan ve objectbu yüzden açık olan bir işlevdir . Ama sanırım bu bir zevk meselesi. ok
Rotareti

3
ES5 lezzetiyle ilk versiyon:Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
Nörotransmitter

1
Bir satır, işlevsiz:Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
Paul Slm

7
Kapsamlı olmaya çalıştığımız için değişmez bir çözüm görmek güzel olabilir. Bunlar kaynak nesneyi mutasyona uğratıyor ve nesne mutasyona uğradığı için aslında gereksiz olan nesneyi aldatıcı bir şekilde geri veriyor. Yeni başlayanlar döndürülen nesne değerini alır ve kaynak nesnelerinin neden değiştirildiğini merak eder.
Mike McLin

2
5) Dizilerle çalışmaz (Object.keys, dizi konum numaralarını öğelerin anahtarı olarak döndürür). Muhtemelen başkalarının bu sorunu var, ancak 5'i test ederken buldum.
Eelco

95

Lodash veya underscore.js kullanıyorsanız, işte basit bir çözüm:

var obj = {name: 'John', age: null};

var compacted = _.pickBy(obj);

Bu sadece lodash 4, pre lodash 4 veya underscore.js ile çalışır _.pick(obj, _.identity);


1
Parlak! Teşekkür ederim! FYI, benim için açık olmayan şey, şu şekilde de kullanabilmeniz: foo (). Then (_. PickBy); // boş sonuçları filtreleme
Maciej Gurban

29
Nesne 0 veya boş dizeler gibi yanlış değerler içeriyorsa, bunun istenen sonucu vermeyeceğini unutmayın. O zaman _.omit(obj, _.isUndefined)daha iyidir.
JHH

5
@JHH null'ları atlamaz _.isUndefined, _.omitBy(obj, _.isNil)her ikisini de atlamak için kullanın undefinedvenull
Lukasz Wiktor

@LukaszWiktor Doğru, soru undefined veya null istedi.
JHH

88

ES6 + için en kısa bir astar

Tüm falsy değerleri Filtre ( "", 0, false, null, undefined)

Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})

Filtre nullve undefineddeğerler:

Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})

SADECE Filtrele null

Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})

SADECE Filtrele undefined

Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})

Özyinelemeli Çözümler: Filtreler nullveundefined

Nesneler için:

const cleanEmpty = obj => Object.entries(obj)
        .map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
        .reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});

Nesneler ve Diziler için:

const cleanEmpty = obj => {
  if (Array.isArray(obj)) { 
    return obj
        .map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
        .filter(v => !(v == null)); 
  } else { 
    return Object.entries(obj)
        .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
        .reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
  } 
}

10
Bu tek cevap olmalı! Bu parçacıkların her biri eskisinin mutasyona uğramayacağı yeni bir nesne oluşturacaktır. Bu tercih edilir! Küçük bir not sadece kullanırsanız ve v == nullkarşı kontrol edecektir . undefinednull
Megajin

cleanEmptyrecursve çözeltiler boş bir nesne döndürür {}tarihi nesneler için
Emmanuel NK

Bir gömlek biraz daha okunaklılık onları harika yapacak !!
zardilior

39

Birisinin Owen'in (ve Eric'in) cevabının özyinelemeli bir versiyonuna ihtiyacı varsa, işte burada:

/**
 * Delete all null (or undefined) properties from an object.
 * Set 'recurse' to true if you also want to delete properties in nested objects.
 */
function delete_null_properties(test, recurse) {
    for (var i in test) {
        if (test[i] === null) {
            delete test[i];
        } else if (recurse && typeof test[i] === 'object') {
            delete_null_properties(test[i], recurse);
        }
    }
}

For döngüsü başladıktan sonra, nesneyi hasOwnPropertykullanarak kontrol etmelisinizif(test.hasOwnProperty(i)) { ... }
Augie Gardner

@AugieGardner Bunu neden kontrol etmek istediğinizi merak ediyorum - isterseniz lütfen açıklayınız. (Devralınan mülklerin kontrolünü engellemez mi?)
Wumms

24

JSON.stringify tanımlanmamış anahtarları kaldırır.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}

Bu benim için derin bir nesne için işe yaramadı, ama Wumm'un yukarıdaki cevabı işe yaradı.
Suman

1
Eğer gerekiyorsa nullolarak tedavi edilmesi undefineddaha fazla bilgi için, kullanım yerine fonksiyonunu bu cevaba bakın: stackoverflow.com/questions/286141/...
Hooman Askari

Bunun nulldeğerleri kaldırmayacağını unutmayın . Deneyin: let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }ve sonra console.log(removeUndefined(a)). Soru undefinedve nulldeğerler hakkındaydı.
mayid

13

Muhtemelen deleteanahtar kelimeyi arıyorsunuz .

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;

4
Yukarıda yaptığı budur, bu hala nesnede tanımsız bırakır.
Josh Bedo

10

nullVe undefineddeğerleri filtrelenmiş bir nesneyi döndürmek için mümkün olan en basit Lodash çözümü .

_.omitBy(obj, _.isNil)


bu şimdiye kadarki en temiz çözüm!
Jee Mok

9

JSON.stringifyReplacer parametresinin bir kombinasyonunu kullanabilir ve JSON.parsebir nesneye geri dönüştürebilirsiniz. Bu yöntemin kullanılması, iç içe nesneler içindeki tüm iç içe anahtarların değiştirilmesinin de yapıldığı anlamına gelir.

Örnek Nesne

var exampleObject = {
  string: 'value',
  emptyString: '',
  integer: 0,
  nullValue: null,
  array: [1, 2, 3],
  object: {
    string: 'value',
    emptyString: '',
    integer: 0,
    nullValue: null,
    array: [1, 2, 3]
  },
  arrayOfObjects: [
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    },
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    }
  ]
};

Replacer İşlevi

function replaceUndefinedOrNull(key, value) {
  if (value === null || value === undefined) {
    return undefined;
  }

  return value;
}

Nesneyi Temizle

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);

CodePen örneği


6

Kullanılması Ramda # pickBy tüm kaldıracak null, undefinedve falsedeğerleri:

const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)

@Manroe'nin belirttiği gibi, falsedeğerleri kullanmak için isNil():

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)

1
(v) => !R.isNil(v)Muhtemelen OP'nin sorusu için daha iyi bir seçimdir, falseya da diğer sahte değerler de reddedilirseR.identity
manroe

6

İşlevsel ve değişmez yaklaşım, .filtergerekenden daha fazla nesne yaratmadan veya yaratmadan

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})

Çok özlü bir cevap. Ayrıca null denetimi sadece değiştirmek eklemek için obj[key] === undefinediçinobj[key] === undefined || obj[key] === null
user3658510

Yukarıdaki yaklaşımın küçük bir varyasyonu: koşullu olarak böyle obj obj özelliğine de yayılabilirconst omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
Kevin K.

6

Json.stringify'ın replacer argümanını kullanarak bir satırda yinelemeli kaldırma yapabilirsiniz

const removeEmptyValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)

Kullanımı:

removeEmptyValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

Emmanuel'in yorumunda belirtildiği gibi, bu teknik yalnızca veri yapınız yalnızca JSON formatına (dizeler, sayılar, listeler, vb.) Yerleştirilebilecek veri türleri içeriyorsa işe yaradı.

(Bu cevap yeni kullanmaya güncellendi Nullish Birleştirme operatörü tarayıcı desteği ihtiyaçlarına bağlı olarak yerine bu işlevi kullanmak isteyebilirsiniz. (k,v) => v!=null ? v : undefined)


1
Bu dönüştürür dizeleri, tarihi nesneleri dönüştürür NaNiçin nullkaldırılmaz hangi.
Emmanuel NK

5

!durum ile daha kısa yapabilirsiniz

var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];

Kullanımda hatırlayın: @semicolor'un yorumlarda duyurduğu gibi: Değer, yanlış veya sıfır boş bir dize ise özellikleri de siler


11
Değer, false veya sıfır olarak boş bir dize olduğunda da bu özellik silinir.
Noktalı virgül

3
Bu tam olarak ne bir JSON isteğinden istenmeyen alanları kaldırmak için aradığını. Teşekkürler!
Phrozen

Yerine [null, undefined].includes(r[k])kullanın !r[k].
selmansamet

5

Daha kısa ES6 saf çözümü, bir diziye dönüştürün, filtre işlevini kullanın ve bir nesneye geri dönüştürün. Ayrıca bir işlev yapmak kolay olurdu ...

Btw. bu ile .length > 0boş bir dize / dizi olup olmadığını kontrol, bu yüzden boş anahtarları kaldıracak.

const MY_OBJECT = { f: 'te', a: [] }

Object.keys(MY_OBJECT)
 .filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
 .reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});

JS BIN https://jsbin.com/kugoyinora/edit?js,console


1
Güzel fonksiyonel çözüm
puiu

Bunu severim! Ama hepsini kaldırmayı düşünüyorum nullve undefinedsadece kullanımı daha kolay olurdu MY_OBJECT[f] != null. Geçerli çözümünüz, boş olmayan dizeler / listeler hariç her şeyi kaldırır ve değerler olduğunda bir hata atarnull
Rotareti

Doğru, ayrıca / chain birden çok kullanabilirsiniz filter, daha okunabilir olurdu.
Michael J. Zoidl

Eğer biraz genelleme yaparsanız ben loadash's ne yakın olsun düşünüyorum omit, çağırmadan önce obj var kontrol etmelisiniz Object.keys:const omit = (obj, filter) => obj && Object.keys(obj).filter(key => !filter(obj[key])).reduce((acc,key) => {acc[key] = obj[key]; return acc}, {});
icc97

Güzel, ancak herhangi bir tam sayı değeri bu yaklaşımla kaldırılacaktır.
Ghis

4

4 satır saf ES7 çözümü istiyorsanız:

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

Veya daha okunabilir sürümü tercih ediyorsanız:

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

Bu, boole değerlerini koruyacak ve dizileri de temizleyecektir. Temizlenmiş bir kopya döndürerek orijinal nesneyi de korur.


4

Projemde aynı senaryo var ve aşağıdaki yöntemi kullanarak elde ettim.

Tüm veri türleriyle çalışır, yukarıda belirtilen az sayıda tarih ve boş dizilerle çalışmaz.

removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) {
   Object.keys(obj).forEach(key => {
  if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
    delete obj[key];
  } else if (obj[key] && typeof obj[key] === 'object') {
    this.removeEmptyKeysFromObject(obj[key]);
  } else if (obj[key] == null || obj[key] === '') {
    delete obj[key];
  }

  if (obj[key]
    && typeof obj[key] === 'object'
    && Object.keys(obj[key]).length === 0
    && Object.prototype.toString.call(obj[key]) !== '[object Date]') {
    delete obj[key];
  }
});
  return obj;
}

herhangi bir nesneyi bu işleve ilet removeEmptyKeysFromObject ()


4

Derin bir arama için aşağıdaki kodu kullandım, belki bu soruya bakan herkes için yararlı olacaktır (döngüsel bağımlılıklar için kullanılamaz):

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

3

Yerinde mutasyon yapmak istemiyorsanız, ancak null / undefined kaldırılmış bir klonu döndürürseniz, ES6 azaltma işlevini kullanabilirsiniz.

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

3

Özelliği silmek yerine, null olmayan anahtarlarla yeni bir nesne de oluşturabilirsiniz.

const removeEmpty = (obj) => {
  return Object.keys(obj).filter(key => obj[key]).reduce(
    (newObj, key) => {
      newObj[key] = obj[key]
      return newObj
    }, {}
  )
}

3

Üzerinde piggypack için Ben'in cevap lodash en kullanarak bu sorunu çözmek için nasıl _.pickBy:, ayrıca kardeş kütüphanede bu sorunu çözebilir Underscore.js 'ın _.pick.

var obj = {name: 'John', age: null};

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

Bakınız: JSFiddle Örneği


1
bu boş dizi döndürür, ayrıca obj adını nesneye değiştirdiniz
Stephen DuMont

Teşekkürler Stephen! Şimdi nasıl? Cevabımı bir JSFiddle bağlantısı içerecek şekilde güncelledim.
Alex Johnson

_.omit (obj, _.isEmpty) kullanmayı deneyin; bu daha kavramsal olarak saftır ve boş dize içerecektir.
Stephen DuMont

3

bir azaltma yardımcısı hile yapabilir (tip kontrolü olmadan) -

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

2

Birinin undefinedderin arama kullanarak bir nesneden değerleri kaldırması gerekiyorsa, lodashişte kullandığım kod. Tüm boş değerleri ( null/ undefined) kaldırmak için değiştirmek oldukça basittir .

function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}


1

Eslint kullanıyorsanız ve param yeniden atama kuralını atlamaktan kaçınmak istiyorsanız, Object.assign öğesini oldukça zarif bir ES6 çözümü için .reduce ve hesaplanan özellik adıyla birlikte kullanabilirsiniz:

const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

1

nullsES6 kullanarak bir nesneyi yalnızca nesneyi mutasyona uğratmadan kaldırmanın işlevsel bir yolu reduce:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

Troll yorumu Bu konuda işlevsel bir model olmakla ilgili iki şey: fonksiyon içinde stripNullsakümülatör fonksiyonunun kapsamının dışından bir referans kullanır; ayrıca akümülatör fonksiyonu içinde filtreleyerek endişeleri karıştırır. Eg (örn. Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});) Evet, filtrelenmiş ürünler üzerinde iki kez ilmek yapacak, ancak gerçekleşen mükemmel kayıp ihmal edilebilir.
Jason Cust

1

...Yayım sözdizimini aşağıdaki forEachgibi bir şey kullanarak da kullanabilirsiniz :

let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};

Object.keys(obj).forEach(val => {
  const newVal = obj[val];
  cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});

console.info(cleanObj);

1

Nesneyi yerinde temizleyin

// General cleanObj function
const cleanObj = (valsToRemoveArr, obj) => {
   Object.keys(obj).forEach( (key) =>
      if (valsToRemoveArr.includes(obj[key])){
         delete obj[key]
      }
   })
}

cleanObj([undefined, null], obj)

Saf fonksiyon

const getObjWithoutVals = (dontReturnValsArr, obj) => {
    const cleanObj = {}
    Object.entries(obj).forEach( ([key, val]) => {
        if(!dontReturnValsArr.includes(val)){
            cleanObj[key]= val
        } 
    })
    return cleanObj
}

//To get a new object without `null` or `undefined` run: 
const nonEmptyObj = getObjWithoutVals([undefined, null], obj)

Bu güzel, muhtemelen tek astarlı bir çözümdür
rekam

1

Bir nesneden boş öznitelikleri kaldırmak için JSON.stringify ve JSON.parse komutlarını kullanabiliriz.

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });

Obj'nin JSON serileştirilebilir olmasını sağladığınız sürece bu hile aslında geçerlidir. Ve derin de çalışıyor.
Polv

Geçersiz dizi ve nesne karşılaştırması ( {} != {}ve [] != []), ancak aksi takdirde yaklaşım geçerli
Aivaras

1

İşte kapsamlı bir özyinelemeli işlev (başlangıçta @chickens tarafından geliştirilen):

  • söylediklerini tekrar tekrar kaldır defaults=[undefined, null, '', NaN]
  • Normal nesneleri, dizileri ve Date nesnelerini doğru şekilde işleme
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}

KULLANIM:

// based off the recursive cleanEmpty function by @chickens. 
// This one can also handle Date objects correctly 
// and has a defaults list for values you want stripped.

const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}


// testing

console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: new Date(),
      c: ''
    }]
  },
  g: NaN,
  h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: '',
      c: new Date()
    }]
  },
  g: [0, 1, 2, 3, 4],
  h: '',
}, [undefined, null]))


0

Saf / fonksiyonel yaklaşımı tercih ediyorsanız

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
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.