Apa cara yang baik dan singkat untuk menghapus nilai dari suatu objek pada kunci tertentu tanpa mengubah objek aslinya?
Saya ingin melakukan sesuatu seperti:
let o = {firstname: 'Jane', lastname: 'Doe'};
let o2 = doSomething(o, 'lastname');
console.log(o.lastname); // 'Doe'
console.log(o2.lastname); // undefined
Saya tahu ada banyak perpustakaan kekekalan untuk tugas-tugas semacam itu, tetapi saya ingin pergi tanpa perpustakaan. Tetapi untuk melakukan ini, persyaratannya adalah memiliki cara yang mudah dan singkat yang dapat digunakan di seluruh kode, tanpa mengabstraksi metode sebagai fungsi utilitas.
Misalnya untuk menambahkan nilai, saya melakukan hal berikut:
let o2 = {...o1, age: 31};
Ini cukup singkat, mudah diingat dan tidak memerlukan fungsi utilitas.
Apakah ada sesuatu seperti ini untuk menghapus nilai? ES6 sangat disambut.
Terima kasih banyak!
javascript
immutability
amann
sumber
sumber
Jawaban:
Memperbarui:
Anda dapat menghapus properti dari objek dengan tugas Penghancuran yang rumit :
const doSomething = (obj, prop) => { let {[prop]: omit, ...res} = obj return res }
Padahal, jika nama properti yang ingin Anda hapus bersifat statis, Anda dapat menghapusnya dengan satu baris sederhana:
let {lastname, ...o2} = o
Cara termudah adalah denganAtau Anda bisa mengkloning objek Anda sebelum memutasinya:const doSomething = (obj, prop) => { let res = Object.assign({}, obj) delete res[prop] return res }
Atau Anda dapat menggunakan
omit
fungsi darilodash
pustaka utilitas :let o2 = _.omit(o, 'lastname')
Ini tersedia sebagai bagian dari paket lodash , atau sebagai paket lodash.omit yang berdiri sendiri .
sumber
a2 = a1.filter(el => el.id !== id)
untuk menghilangkan elemen dalam array dengan id tertentu. Apakah tidak ada benda yang seperti itu?keep_if
const {[prop], ...rest} = obj
berhasil? Mengapa Anda harus menetapkan properti yang diekstrak ke variabel baru (omit
dalam kasus ini)?no-unused-vars
aturan Anda , itu hanya regex.Dengan objek ES7 yang merusak:
const myObject = { a: 1, b: 2, c: 3 }; const { a, ...noA } = myObject; console.log(noA); // => { b: 2, c: 3 }
sumber
a
disimpan dalam variabelconst x = 'a'
?const { a,b, ...noA } = myObject;
console.log(noA); // => {c: 3 }
solusi satu baris
const removeKey = (key, {[key]: _, ...rest}) => rest;
sumber
Seperti yang disarankan dalam komentar di atas jika Anda ingin memperpanjang ini untuk menghapus lebih dari satu item dari Anda yang
object
ingin saya gunakanfilter
. danreduce
misalnya
const o = { "firstname": "Jane", "lastname": "Doe", "middlename": "Kate", "age": 23, "_id": "599ad9f8ebe5183011f70835", "index": 0, "guid": "1dbb6a4e-f82d-4e32-bb4c-15ed783c70ca", "isActive": true, "balance": "$1,510.89", "picture": "http://placehold.it/32x32", "eyeColor": "green", "registered": "2014-08-17T09:21:18 -10:00", "tags": [ "consequat", "ut", "qui", "nulla", "do", "sunt", "anim" ] }; const removeItems = ['balance', 'picture', 'tags'] console.log(formatObj(o, removeItems)) function formatObj(obj, removeItems) { return { ...Object.keys(obj) .filter(item => !isInArray(item, removeItems)) .reduce((newObj, item) => { return { ...newObj, [item]: obj[item] } }, {}) } } function isInArray(value, array) { return array.indexOf(value) > -1; }
sumber
Untuk menambahkan beberapa bumbu membawa Kinerja. Periksa utas ini di bawah
https://github.com/googleapis/google-api-nodejs-client/issues/375
Anda juga bisa menggunakan cara yang merusak
const {remov1, remov2, ...new} = old; old = new;
Dan contoh yang lebih praktis:
this._volumes[this._minCandle] = undefined; { const {[this._minCandle]: remove, ...rest} = this._volumes; this._volumes = rest; }
Seperti yang Anda lihat, Anda dapat menggunakan
[somePropsVarForDynamicName]: scopeVarName
sintaks untuk nama dinamis. Dan Anda bisa meletakkan semua dalam tanda kurung (blok baru) sehingga sisanya akan dikumpulkan setelah itu.Berikut tesnya:
eksekutif:
Atau kita bisa pergi dengan beberapa fungsi seperti
function deleteProps(obj, props) { if (!Array.isArray(props)) props = [props]; return Object.keys(obj).reduce((newObj, prop) => { if (!props.includes(prop)) { newObj[prop] = obj[prop]; } return newObj; }, {}); }
untuk naskah ketikan
function deleteProps(obj: Object, props: string[]) { if (!Array.isArray(props)) props = [props]; return Object.keys(obj).reduce((newObj, prop) => { if (!props.includes(prop)) { newObj[prop] = obj[prop]; } return newObj; }, {}); }
Pemakaian:
let a = {propH: 'hi', propB: 'bye', propO: 'ok'}; a = deleteProps(a, 'propB'); // or a = deleteProps(a, ['propB', 'propO']);
Dengan cara ini objek baru dibuat. Dan properti cepat dari objek disimpan. Yang bisa penting atau penting. Jika pemetaan dan objek akan diakses berkali-kali.
Juga bergaul
undefined
bisa menjadi cara yang baik untuk dilakukan. Bila Anda mampu membelinya. Dan untuk kunci Anda juga dapat memeriksa nilainya. Misalnya untuk mendapatkan semua kunci aktif Anda melakukan sesuatu seperti:const allActiveKeys = Object.keys(myObj).filter(k => myObj[k] !== undefined); //or const allActiveKeys = Object.keys(myObj).filter(k => myObj[k]); // if any false evaluated value is to be stripped.
Undefined tidak cocok untuk daftar besar. Atau pengembangan dari waktu ke waktu dengan banyak props yang akan masuk. Karena penggunaan memori akan terus bertambah dan tidak akan pernah dibersihkan. Jadi tergantung dari penggunaannya. Dan hanya membuat objek baru sepertinya merupakan cara yang baik.
Kemudian
Premature optimization is the root of all evil
akan dimulai. Jadi, Anda perlu waspada terhadap trade off. Dan apa yang dibutuhkan dan apa yang tidak.Catatan tentang _.omit () dari lodash
Ini dihapus dari versi 5. Anda tidak dapat menemukannya di repo. Dan di sini ada masalah yang membicarakannya.
https://github.com/lodash/lodash/issues/2930
v8
Anda dapat memeriksa ini yang merupakan bacaan yang baik https://v8.dev/blog/fast-properties
sumber
Masalah saya dengan jawaban yang diterima, dari standar aturan ESLint, jika Anda mencoba untuk merusak:
const { notNeeded, alsoNotNeeded, ...rest } = { ...ogObject };
2 variabel baru,
notNeeded
danalsoNotNeeded
mungkin memunculkan peringatan atau kesalahan tergantung pada pengaturan Anda karena sekarang tidak digunakan. Jadi mengapa membuat vars baru jika tidak digunakan?Saya pikir Anda harus
delete
benar-benar menggunakan fungsinya.sumber
no-unused-vars
Aturan sebenarnya memiliki opsiignoreRestSiblings
sekarang untuk menutupi kasus penggunaan ini: eslint.org/docs/rules/no-unused-vars#ignorerestsiblingsdengan lodash cloneDeep dan hapus
(catatan: klon lodash dapat digunakan sebagai pengganti untuk objek dangkal)
const obj = {a: 1, b: 2, c: 3} const unwantedKey = 'a' const _ = require('lodash') const objCopy = _.cloneDeep(obj) delete objCopy[unwantedKey] // objCopy = {b: 2, c: 3}
sumber
Untuk kode saya, saya menginginkan versi singkat untuk nilai kembalian map () tetapi solusi operasi multiline / mutli "jelek". Fitur utamanya adalah yang lama
void(0)
yang memutuskan untukundefined
.let o2 = {...o, age: 31, lastname: void(0)};
Properti tetap berada di objek:
console.log(o2) // {firstname: "Jane", lastname: undefined, age: 31}
tetapi kerangka transmisi membunuhnya untuk saya (bc stringify):
console.log(JSON.stringify(o2)) // {"firstname":"Jane","age":31}
sumber