Saya memiliki objek JS datar:
{a: 1, b: 2, c: 3, ..., z:26}
Saya ingin mengkloning objek kecuali satu elemen:
{a: 1, c: 3, ..., z:26}
Apa cara termudah untuk melakukan ini (lebih suka menggunakan es6 / 7 jika mungkin)?
Saya memiliki objek JS datar:
{a: 1, b: 2, c: 3, ..., z:26}
Saya ingin mengkloning objek kecuali satu elemen:
{a: 1, c: 3, ..., z:26}
Apa cara termudah untuk melakukan ini (lebih suka menggunakan es6 / 7 jika mungkin)?
Jawaban:
Jika Anda menggunakan Babel, Anda dapat menggunakan sintaks berikut untuk menyalin properti b dari x ke dalam variabel b dan kemudian menyalin sisa properti ke dalam variabel y :
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
dan itu akan diubah menjadi:
"use strict";
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
var x = { a: 1, b: 2, c: 3, z: 26 };
var b = x.b;
var y = _objectWithoutProperties(x, ["b"]);
let x = [{a: 1, b: 2, c: 3, z:26}, {a: 5, b: 6, c: 7, z:455}];
ignoreRestSiblings
yang ditambahkan di v3.15.0 (3 Februari 2017). Lihat: commit c59a0ba
b
ruang lingkup.
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
atau jika Anda menerima properti tidak terdefinisi:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
Untuk menambah jawaban Ilya Palkin: Anda bahkan dapat menghapus kunci secara dinamis:
const x = {a: 1, b: 2, c: 3, z:26};
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object;
return otherKeys;
}
console.log(objectWithoutKey(x, 'b')); // {a: 1, c: 3, z:26}
console.log(x); // {a: 1, b: 2, c: 3, z:26};
Sumber:
_
yang diizinkan untuk variabel yang tidak ingin Anda gunakan?
var b = {a:44, b:7, c:1}; let {['a']:z, ...others} = b; console.log(z , others ); // logs: 44, {b:7, c:1}
Bagi yang tidak bisa menggunakan ES6, Anda bisa menggunakan lodash
atau underscore
.
_.omit(x, 'b')
Atau ramda
.
R.omit('b', x)
_.omit(x, 'b')
delete
.
Saya menggunakan ESNext one liner ini
const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = (({ b, c, ...o }) => o)(obj) // remove b and c
console.log(clone)
Jika Anda membutuhkan fungsi tujuan umum:
function omit(obj, props) {
props = props instanceof Array ? props : [props]
return eval(`(({${props.join(',')}, ...o}) => o)(obj)`)
}
// usage
const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = omit(obj, ['b', 'c'])
console.log(clone)
map
Anda dapat melakukan:(({b, c, ...others}) => ({...others}))(obj)
Anda dapat menulis fungsi pembantu sederhana untuk itu. Lodash memiliki fungsi serupa dengan nama yang sama: menghilangkan
function omit(obj, omitKey) {
return Object.keys(obj).reduce((result, key) => {
if(key !== omitKey) {
result[key] = obj[key];
}
return result;
}, {});
}
omit({a: 1, b: 2, c: 3}, 'c') // {a: 1, b: 2}
Juga, perhatikan bahwa ini lebih cepat dari Object.assign dan hapus kemudian: http://jsperf.com/omit-key
Mungkin kira-kira seperti ini:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
Apakah ini cukup baik? Atau tidak dapat c
benar - benar disalin?
Menggunakan Destrukturisasi Objek
const omit = (prop, { [prop]: _, ...rest }) => rest;
const obj = { a: 1, b: 2, c: 3 };
const objWithoutA = omit('a', obj);
console.log(objWithoutA); // {b: 2, c: 3}
_
tidak menyelesaikan masalah untuk ESLint ...
Hei sepertinya Anda mengalami masalah referensi ketika Anda mencoba menyalin objek kemudian menghapus properti. Di suatu tempat Anda harus menetapkan variabel primitif sehingga javascript membuat nilai baru.
Trik sederhana (mungkin menghebohkan) yang saya gunakan adalah ini
var obj = {"key1":"value1","key2":"value2","key3":"value3"};
// assign it as a new variable for javascript to cache
var copy = JSON.stringify(obj);
// reconstitute as an object
copy = JSON.parse(copy);
// now you can safely run delete on the copy with completely new values
delete copy.key2
console.log(obj)
// output: {key1: "value1", key2: "value2", key3: "value3"}
console.log(copy)
// output: {key1: "value1", key3: "value3"}
JSON.parse(JSON.stringify(Object.assign({}, obj, { key2: undefined })));
. Bahkan tidak perlu menghapusnya, hanya perlu nilai palsu.
Berikut adalah opsi untuk menghilangkan kunci dinamis yang saya yakin belum disebutkan:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
alias removedKey
dan diabaikan. newObj
menjadi { 2: 2, 3: 3, 4: 4 }
. Perhatikan bahwa kunci yang dihapus tidak ada, nilainya tidak hanya diatur ke undefined
.
CARA TERMUDAH
const allAlphabets = {a: 1, b: 2, c: 3, ..., z:26};
const { b, ...allExceptOne } = allAlphabets;
console.log(allExceptOne); // {a: 1, c: 3, ..., z:26}
Lodash omit
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
Anda juga dapat menggunakan operator spread untuk melakukan ini
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
copy
const copy = { ...source, b: undefined }
bermuara persis sama.
Solusi di atas menggunakan penataan menderita dari fakta bahwa Anda memiliki variabel yang digunakan, yang dapat menyebabkan keluhan dari ESLint jika Anda menggunakannya.
Jadi, inilah solusi saya:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
Pada sebagian besar platform (kecuali IE kecuali menggunakan Babel), Anda juga dapat melakukan:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
Bagaimana dengan ini:
let clone = Object.assign({}, value);
delete clone.unwantedKey;
Jika Anda berurusan dengan variabel besar, Anda tidak ingin menyalinnya dan kemudian menghapusnya, karena ini tidak efisien.
Sederhana untuk-loop dengan cek hasOwnProperty harus bekerja, dan itu jauh lebih mudah beradaptasi dengan kebutuhan di masa depan:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
Bagaimana dengan ini? Saya tidak pernah menemukan derai ini di sekitar tetapi saya hanya mencoba untuk mengecualikan satu atau lebih properti tanpa perlu membuat objek tambahan. Ini sepertinya berhasil, tetapi ada beberapa efek samping yang tidak dapat saya lihat. Yang pasti tidak terlalu mudah dibaca.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
Saya melakukannya dengan cara ini, sebagai contoh dari redux Redux saya:
const clone = { ...state };
delete clone[action.id];
return clone;
Dengan kata lain:
const clone = { ...originalObject } // note: original object is not altered
delete clone[unwantedKey] // or use clone.unwantedKey or any other applicable syntax
return clone // the original object without the unwanted key
const { [removeMe]: removedKey, ...newObj } = obj;
- lihat jawaban saya pada pertanyaan ini.
Baru-baru ini saya melakukannya dengan cara yang sangat sederhana:
const obj = {a: 1, b: 2, ..., z:26};
hanya menggunakan operator spread untuk memisahkan properti yang tidak diinginkan:
const {b, ...rest} = obj;
... dan objek.tugaskan untuk mengambil hanya bagian 'sisanya':
const newObj = Object.assign({}, {...rest});
rest
sudah menjadi objek baru - Anda tidak perlu baris terakhir. Plus, ini identik dengan solusi yang diterima.
const x = {obj1: 1, pass: 2, obj2: 3, obj3:26};
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object;
return otherKeys;
}
console.log(objectWithoutKey(x, 'pass'));