Ho un oggetto JS piatto:
{a: 1, b: 2, c: 3, ..., z:26}
Voglio clonare l'oggetto ad eccezione di un elemento:
{a: 1, c: 3, ..., z:26}
Qual è il modo più semplice per farlo (preferendo usare es6 / 7 se possibile)?
Ho un oggetto JS piatto:
{a: 1, b: 2, c: 3, ..., z:26}
Voglio clonare l'oggetto ad eccezione di un elemento:
{a: 1, c: 3, ..., z:26}
Qual è il modo più semplice per farlo (preferendo usare es6 / 7 se possibile)?
Risposte:
Se usi Babel puoi usare la seguente sintassi per copiare la proprietà b da x nella variabile b e quindi copiare il resto delle proprietà nella variabile y :
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
e sarà traspilato in:
"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
che è stata aggiunta in v3.15.0 (3 febbraio 2017). Vedi: commit c59a0ba
b
ambito.
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
o se si accetta che la proprietà non sia definita:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
Per aggiungere alla risposta di Ilya Palkin: puoi persino rimuovere dinamicamente le chiavi:
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};
Fonte:
_
quale è consentito per una variabile che non intendi utilizzare?
var b = {a:44, b:7, c:1}; let {['a']:z, ...others} = b; console.log(z , others ); // logs: 44, {b:7, c:1}
Per coloro che non possono utilizzare ES6, è possibile utilizzare lodash
o underscore
.
_.omit(x, 'b')
Or ramda
.
R.omit('b', x)
delete
.
Uso questo ESLext one liner
const obj = { a: 1, b: 2, c: 3, d: 4 }
const clone = (({ b, c, ...o }) => o)(obj) // remove b and c
console.log(clone)
Se hai bisogno di una funzione generica:
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
puoi fare:(({b, c, ...others}) => ({...others}))(obj)
Puoi scrivere una semplice funzione di supporto per questo. Lodash ha una funzione simile con lo stesso nome: ometti
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}
Inoltre, nota che è più veloce di Object.assign ed elimina quindi: http://jsperf.com/omit-key
Forse qualcosa del genere:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
È abbastanza buono? O non puoi c
davvero copiarlo?
Utilizzo della distruzione degli oggetti
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}
_
non risolve il problema con ESLint ...
Ehi sembra che ti imbatti in problemi di riferimento quando stai provando a copiare un oggetto e poi a eliminare una proprietà. Da qualche parte devi assegnare variabili primitive così javascript fa un nuovo valore.
Il trucco semplice (può essere orrendo) che ho usato era questo
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 })));
. Non è nemmeno necessario eliminarlo, necessita solo di un valore errato.
Ecco un'opzione per omettere i tasti dinamici che credo non sia ancora stata menzionata:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
è aliasato removedKey
e ignorato. newObj
diventa { 2: 2, 3: 3, 4: 4 }
. Si noti che la chiave rimossa non esiste, il valore non è stato semplicemente impostato su undefined
.
MODO PIÙ SEMPLICE
const allAlphabets = {a: 1, b: 2, c: 3, ..., z:26};
const { b, ...allExceptOne } = allAlphabets;
console.log(allExceptOne); // {a: 1, c: 3, ..., z:26}
Lodash omette
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
Puoi anche usare l'operatore spread per fare questo
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 }
si riduce esattamente allo stesso.
Le soluzioni sopra usando la strutturazione soffrono del fatto che hai una variabile usata, che potrebbe causare lamentele da ESLint se la stai usando.
Quindi ecco le mie soluzioni:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
Sulla maggior parte delle piattaforme (tranne IE a meno che non usi Babel), puoi anche fare:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
Cosa ne pensi di questo:
let clone = Object.assign({}, value);
delete clone.unwantedKey;
Se hai a che fare con una variabile enorme, non vuoi copiarla e quindi eliminarla, poiché ciò sarebbe inefficiente.
Un semplice for-loop con un controllo hasOwnProperty dovrebbe funzionare ed è molto più adattabile alle esigenze future:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
Che dire di questo? Non ho mai trovato questo scalpiccio in giro, ma stavo solo cercando di escludere una o più proprietà senza la necessità di creare un oggetto in più. Questo sembra fare il lavoro ma ci sono alcuni effetti collaterali che non riesco a vedere. Di sicuro non è molto leggibile.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
L'ho realizzato in questo modo, ad esempio dal mio riduttore Redux:
const clone = { ...state };
delete clone[action.id];
return clone;
In altre parole:
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;
- vedi la mia risposta su questa domanda.
Di recente l'ho fatto in un modo molto semplice:
const obj = {a: 1, b: 2, ..., z:26};
basta usare l' operatore spread per separare la proprietà indesiderata:
const {b, ...rest} = obj;
... e object.assign per prendere solo la parte 'resto':
const newObj = Object.assign({}, {...rest});
rest
è già un nuovo oggetto: non è necessaria l'ultima riga. Inoltre, questo è identico alla soluzione accettata.
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'));