Hapus atribut kosong dari Objek di Javascript


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

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


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


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

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

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

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;

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)


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


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)

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

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)


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


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


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.


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


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

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

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

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


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

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


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 }

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

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

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)

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

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


0

Jika Anda lebih suka pendekatan murni / fungsional

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.