Hapus atribut kosong dari Objek di Javascript

266

Bagaimana cara menghapus semua atribut yang ada undefined atau nulldalam objek JavaScript?

(Pertanyaan serupa dengan yang ini untuk Array)

abhijit
sumber
19
Sangat menyarankan orang mengabaikan peringkat teratas dan pindah ke versi ES6 / ES7 di sini, stackoverflow.com/a/38340730/124486
Evan Carroll
2
Juga ES6 satu liner tanpa objek bermutasi ada di sini: stackoverflow.com/a/57625661/1602301
ayam

Jawaban:

184

Anda dapat mengulangi objek:

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

Jika Anda khawatir tentang penghapusan properti ini yang tidak menjalankan rantai proptipe objek, Anda juga dapat:

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

Beberapa catatan tentang nol vs tidak terdefinisi:

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

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

test.notaprop === undefined; // true
test.notaprop == undefined; // true
Owen
sumber
2
Menambahkan koreksi cepat. Variabel "i" yang tidak dideklarasikan akan bocor ke lingkup luar jika cuplikan ini pernah digunakan dalam suatu fungsi.
Eric Nguyen
4
Anda dapat menyederhanakan (test [i] === null || test [i] === tidak terdefinisi) menjadi (test [i] == null)
jaf0
Hai, @EricNguyen, tidak seperti C dan beberapa bahasa lainnya, javascript tidak memiliki lingkup blok untuk variabel (hanya lingkup fungsi), dengan demikian, variabel saya akan selalu bocor ke dalam lingkup setelah blok for .
Gerardo Lima
1
@ GerardoLima, ya. Saya agak berasumsi bahwa ini semua akan dibungkus dalam suatu fungsi. Apa yang saya maksud (dengan asumsi semua dibungkus dengan fungsi) adalah bahwa Anda memerlukan deklarasi var atau saya akan bocor bahkan di luar lingkup fungsi.
Eric Nguyen
Ini juga akan berulang melalui prototipe objek primitif - yang dalam banyak kasus tidak diinginkan. stackoverflow.com/a/2869372/1612318
Rotareti
427

Menggunakan beberapa ES6 / ES2015 :

1) Satu kalimat sederhana untuk menghapus item sebaris tanpa tugas:

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

jsbin

2) Contoh ini telah dihapus ...

3) Contoh pertama ditulis sebagai fungsi:

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

jsbin

4) Fungsi ini menggunakan rekursi untuk menghapus item dari objek bersarang juga:

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) Ini mirip dengan 4), tetapi alih-alih memutasikan objek sumber secara langsung, ia mengembalikan objek baru.

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) Pendekatan fungsional untuk 4b) berdasarkan jawaban @ MichaelJ.Zoidl menggunakan filter()dan reduce(). Ini juga mengembalikan objek baru:

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) Sama seperti 4) tetapi dengan ES7 / 2016 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) Versi fungsional lain yang menggunakan rekursi dan mengembalikan objek baru dengan ES2019 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) Sama seperti 4) tetapi dalam ES5 polos :

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

Rotareti
sumber
3
@AugustinRiedinger Ketika saya harus memutuskan antara garis-istirahat dan singkatan saya kadang-kadang pergi untuk singkatan jika saya pikir singkatannya adalah kejahatan yang lebih rendah. Kode dalam 5) tidak sulit untuk dipikirkan dan itu adalah fungsi yang menghapus kosong keysdari object, jadi odan kjelas. Tapi saya rasa ini masalah selera.
Rotareti
3
Versi pertama dengan rasa ES5:Object.keys(myObj).forEach(function (key) {(myObj[key] == null) && delete myObj[key]});
Neurotransmitter
1
Satu baris, tanpa fungsi:Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})
Paul Slm
7
Karena kita berusaha untuk teliti, mungkin menyenangkan untuk melihat solusi yang tidak berubah. Ini bermutasi objek sumber dan menipu mengembalikan objek yang sebenarnya tidak perlu karena objek telah dimutasi. Pemula akan menangkap nilai objek yang dikembalikan dan bertanya-tanya mengapa objek sumbernya juga dimodifikasi.
Mike McLin
2
5) Tidak berfungsi dengan array (Object.keys akan mengembalikan nomor posisi array sebagai kunci untuk elemen). Mungkin orang lain memiliki masalah ini, tetapi saya menemukan ini ketika menguji 5.
Eelco
95

Jika Anda menggunakan lodash atau underscore.js, berikut adalah solusi sederhana:

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

var compacted = _.pickBy(obj);

Ini hanya akan bekerja dengan lodash 4, pre lodash 4 atau underscore.js, gunakan _.pick(obj, _.identity);

Ben
sumber
1
Cemerlang! Terima kasih! FYI, yang tidak jelas bagi saya adalah Anda bisa menggunakannya juga seperti ini: foo (). Then (_. PickBy); // memfilter hasil kosong
Maciej Gurban
29
Perhatikan bahwa ini tidak akan memiliki hasil yang diinginkan jika objek berisi nilai-nilai palsu seperti 0 atau string kosong. Maka _.omit(obj, _.isUndefined)lebih baik.
JHH
5
@JHH _.isUndefinedtidak menghilangkan nulls, gunakan _.omitBy(obj, _.isNil)untuk menghilangkan keduanya undefineddannull
Lukasz Wiktor
@LukaszWiktor Benar, pertanyaannya memang meminta tidak terdefinisi atau null.
JHH
88

Satu liner terpendek untuk ES6 +

Menyaring semua nilai falsy ( "", 0, false, null, undefined)

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

Filter nulldan undefinednilai:

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

Saringan HANYA null

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

Saringan HANYA undefined

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

Solusi Rekursif: Filter nulldanundefined

Untuk Objek:

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

Untuk Objek dan Array:

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)), {});
  } 
}
ayam
sumber
10
Ini harus menjadi satu-satunya jawaban! Setiap cuplikan ini akan menghasilkan objek baru di mana yang lama tidak akan dimutasi. Ini lebih disukai! Sedikit catatan jika Anda hanya menggunakan v == nullAnda akan memeriksa undefineddan null.
Megajin
yang cleanEmptysolusi recursve akan kembali objek yang kosong {}untuk Tanggal benda
Emmanuel NK
Sedikit keterbacaan yang lebih dalam satu garis akan membuat mereka luar biasa !!
zardilior
39

Jika seseorang membutuhkan versi rekursif dari jawaban Owen (dan Eric), ini dia:

/**
 * 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);
        }
    }
}
Wah
sumber
Setelah for loop dimulai, Anda harus memeriksa apakah objek tersebut hasOwnPropertymenggunakanif(test.hasOwnProperty(i)) { ... }
Augie Gardner
@ AgieGardner Saya ingin tahu mengapa Anda ingin memeriksa ini - tolong jelaskan jika Anda mau. (Bukankah itu akan mencegah pengecekan properti yang diwariskan?)
Wumms
24

JSON.stringify menghapus kunci yang tidak ditentukan.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}
Alexandre Farber
sumber
Ini tidak berhasil bagi saya untuk objek yang mendalam, tetapi jawaban Wumm di atas melakukannya.
Suman
1
Jika Anda perlu nulldiperlakukan sebagai undefinedmenggunakan fungsi penggantian, untuk info lebih lanjut lihat jawaban ini: stackoverflow.com/questions/286141/…
Hooman Askari
Perlu diketahui bahwa ini tidak menghapus nullnilai. Coba: let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }lalu console.log(removeUndefined(a)). Pertanyaan tentang undefineddan nullnilai - nilai.
mayid
13

Anda mungkin mencari deletekata kunci.

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;
yfeldblum
sumber
4
Inilah yang dia lakukan di atas, ini juga masih menyisakan objek.
Josh Bedo
10

Solusi Lodash yang paling sederhana untuk mengembalikan objek dengan nulldan undefinednilai yang disaring.

_.omitBy(obj, _.isNil)

JeffD23
sumber
ini adalah solusi terbersih sejauh ini!
Jee Mok
9

Anda dapat menggunakan kombinasi JSON.stringifyparameter replacer-nya, dan JSON.parsemengubahnya kembali menjadi objek. Menggunakan metode ini juga berarti penggantian dilakukan untuk semua kunci bersarang di dalam objek bersarang.

Contoh Obyek

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

Fungsi Pengganti

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

  return value;
}

Bersihkan Obyek

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

Contoh CodePen

Alex Mueller
sumber
6

Menggunakan ramda # pickBy Anda akan menghapus semua null, undefineddan falsenilainya:

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

Seperti yang ditunjukkan @manroe, untuk menjaga agar falsenilai tetap digunakan isNil():

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)
Amio.io
sumber
1
(v) => !R.isNil(v)mungkin merupakan pilihan yang lebih baik untuk pertanyaan OP, mengingat bahwa falseatau nilai-nilai palsu lainnya juga akan ditolak olehR.identity
manroe
6

Pendekatan fungsional dan abadi, tanpa .filterdan tanpa menciptakan lebih banyak objek dari yang dibutuhkan

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})
peralmq
sumber
Jawaban yang sangat singkat. Untuk menambahkan cek nol, ganti saja obj[key] === undefinedkeobj[key] === undefined || obj[key] === null
user3658510
sedikit variasi dari pendekatan di atas: Anda juga dapat secara kondisional menyebar di properti obj yang benar seperti ituconst omitFalsy = obj => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...(obj[key] && { [key]: obj[key] }) }), {});
Kevin K.
6

Anda dapat melakukan penghapusan rekursif dalam satu baris menggunakan argumen replacer json.stringify

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

Pemakaian:

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

Seperti disebutkan dalam komentar Emmanuel, teknik ini hanya berfungsi jika struktur data Anda hanya berisi tipe data yang dapat dimasukkan ke dalam format JSON (string, angka, daftar, dll).

(Jawaban ini telah diperbarui untuk menggunakan baru Operator Nullish penggabungan tergantung pada kebutuhan dukungan browser Anda mungkin ingin menggunakan fungsi ini sebagai gantinya:. (k,v) => v!=null ? v : undefined)

Scotty Jamison
sumber
1
ini akan mengonversi objek Date menjadi string, yang dikonversi NaNke objek nullyang tidak dihapus.
Emmanuel NK
5

Anda dapat melakukan lebih pendek dengan !kondisi

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

Ingat dalam penggunaan: seperti yang diumumkan @semicolor dalam komentar: Ini juga akan menghapus properti jika nilainya berupa string kosong, false atau nol

nguyên
sumber
11
Ini juga akan menghapus properti jika nilainya string kosong, salah atau nol.
Titik koma
3
Ini persis seperti yang saya cari untuk menghapus bidang yang tidak diinginkan dari permintaan JSON. Terima kasih!
Phrozen
Gunakan [null, undefined].includes(r[k])sebagai ganti !r[k].
selmansamet
5

Solusi murni ES6 yang lebih pendek, mengubahnya menjadi array, menggunakan fungsi filter dan mengubahnya kembali ke objek. Juga mudah membuat fungsi ...

Btw. dengan ini .length > 0saya periksa apakah ada string / array kosong, sehingga akan menghapus kunci kosong.

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

Michael J. Zoidl
sumber
1
Solusi fungsional yang bagus
puiu
Saya suka ini! Tapi saya pikir untuk menghapus semua nulldan undefinedakan lebih mudah untuk digunakan MY_OBJECT[f] != null. Solusi Anda saat ini menghilangkan semuanya kecuali string kosong / daftar dan melempar kesalahan saat nilainyanull
Rotareti
Benar, Anda juga bisa menggunakan / rantai banyak filter, akan lebih mudah dibaca.
Michael J. Zoidl
Jika Anda menyamaratakan sedikit ini, saya pikir Anda mendekati apa yang dilakukan loadash omit, Anda perlu memeriksa obj yang ada sebelum memanggil 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
Bagus, tetapi nilai integer apa pun akan dihapus dengan pendekatan ini.
Ghis
4

Jika Anda menginginkan 4 baris solusi ES7 murni:

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;

Atau jika Anda lebih suka versi yang lebih mudah dibaca:

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

Ini akan mempertahankan nilai boolean dan akan membersihkan array juga. Ini juga mempertahankan objek asli dengan mengembalikan salinan yang sudah dibersihkan.

DaniOcean
sumber
4

Saya memiliki skenario yang sama dalam proyek saya dan dicapai dengan menggunakan metode berikut.

Ini bekerja dengan semua tipe data, beberapa yang disebutkan di atas tidak bekerja dengan array tanggal dan kosong.

hapusEmptyKeysFromObject.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;
}

meneruskan objek apa pun ke fungsi ini removeEmptyKeysFromObject ()

bharath muppa
sumber
4

Untuk pencarian mendalam saya menggunakan kode berikut, mungkin ini akan berguna bagi siapa pun yang melihat pertanyaan ini (tidak dapat digunakan untuk dependensi siklik):

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;
    }
sam
sumber
3

Jika Anda tidak ingin bermutasi di tempat, tetapi mengembalikan klon dengan null / undefined dihapus, Anda bisa menggunakan fungsi pengurangan ES6.

// 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;
  }, {});
}
bsyk
sumber
3

Alih-alih menghapus properti, Anda juga dapat membuat objek baru dengan kunci yang tidak nol.

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

Untuk piggypack pada jawaban Ben tentang cara untuk memecahkan masalah ini dengan menggunakan lodash ini _.pickBy, Anda juga dapat memecahkan masalah ini di adik perpustakaan: Underscore.js 's _.pick.

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

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

Lihat: Contoh JSFiddle

Alex Johnson
sumber
1
ini mengembalikan array kosong, juga Anda mengubah nama objek ke objek
Stephen DuMont
Stephen terima kasih! Bagaimana kalau sekarang? Saya telah memperbarui jawaban saya untuk menyertakan tautan JSFiddle.
Alex Johnson
coba gunakan _.omit (obj, _.isEmpty); ini lebih murni secara konsep dan akan menyertakan string kosong.
Stephen DuMont
3

seorang pembantu mengurangi bisa melakukan trik (tanpa memeriksa jenis) -

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

Jika seseorang perlu menghapus undefinednilai dari suatu objek dengan pencarian mendalam menggunakan lodashmaka di sini adalah kode yang saya gunakan. Cukup mudah untuk memodifikasinya untuk menghapus semua nilai kosong ( null/ undefined).

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;
  }, {});
}
Łukasz Jagodziński
sumber
1

Dengan Lodash:

_.omitBy({a: 1, b: null}, (v) => !v)
Dana Woodman
sumber
1

Jika Anda menggunakan eslint dan ingin menghindari melanggar aturan no-param-reassign, Anda dapat menggunakan Object.assign bersama dengan .reduce dan nama properti yang dihitung untuk solusi ES6 yang cukup elegan:

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 }
dpmott
sumber
1

Berikut adalah cara fungsional untuk menghapus nullsdari Obyek menggunakan ES6 tanpa bermutasi objek hanya menggunakan reduce:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}
Felippe Nardi
sumber
Komentar Troll Dua hal mengenai ini menjadi pola fungsional: dalam stripNullsfungsi itu menggunakan referensi dari luar ruang lingkup fungsi akumulator; dan itu juga mencampur kekhawatiran dengan memfilter dalam fungsi akumulator. 😝 (mis. Object.entries(o).filter(([k,v]) => v !== null).reduce((o, [k, v]) => {o[k] = v; return o;}, {});) Ya, itu akan mengulang item yang disaring dua kali tetapi kerugian yang disadari di sana dapat diabaikan.
Jason Cust
1

Anda juga dapat menggunakan ...sintaks spread menggunakan forEachsesuatu seperti ini:

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);
Hardik Pithva
sumber
1

Bersihkan benda di tempatnya

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

cleanObj([undefined, null], obj)

Fungsi murni

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)
Ben Carp
sumber
Solusi ini bagus, mungkin satu-liner,
rekam
1

Kita bisa menggunakan JSON.stringify dan JSON.parse untuk menghapus atribut kosong dari suatu objek.

jsObject = JSON.parse(JSON.stringify(jsObject), (key, value) => {
               if (value == null || value == '' || value == [] || value == {})
                   return undefined;
               return value;
           });
Vardaman PK
sumber
Trik ini sebenarnya valid, selama Anda memastikan bahwa Obj adalah JSON-serializable. Dan itu bekerja dalam juga.
Polv
Array dan perbandingan objek tidak valid ( {} != {}dan [] != []), tetapi sebaliknya pendekatan valid
Aivaras
1

Berikut adalah fungsi rekursif yang komprehensif (awalnya didasarkan pada yang oleh @chickens) yang akan:

  • secara rekursif menghapus apa yang Anda katakan defaults=[undefined, null, '', NaN]
  • Menangani objek, array, dan objek Tanggal dengan benar
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
}

PEMAKAIAN:

// 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]))

Emmanuel NK
sumber
0

Jika Anda lebih suka pendekatan murni / fungsional

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
Peter Aron Zentai
sumber