Tengo un objeto JS plano:
{a: 1, b: 2, c: 3, ..., z:26}
Quiero clonar el objeto excepto por un elemento:
{a: 1, c: 3, ..., z:26}
¿Cuál es la forma más fácil de hacer esto (prefiriendo usar es6 / 7 si es posible)?
Tengo un objeto JS plano:
{a: 1, b: 2, c: 3, ..., z:26}
Quiero clonar el objeto excepto por un elemento:
{a: 1, c: 3, ..., z:26}
¿Cuál es la forma más fácil de hacer esto (prefiriendo usar es6 / 7 si es posible)?
Respuestas:
Si usa Babel , puede usar la siguiente sintaxis para copiar la propiedad b de x en la variable b y luego copiar el resto de las propiedades en la variable y :
let x = {a: 1, b: 2, c: 3, z:26};
let {b, ...y} = x;
y se trasladará a:
"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
que se agregó en v3.15.0 (3 de febrero de 2017). Ver: commit c59a0ba
b
alcance.
var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
o si acepta que la propiedad no esté definida:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
Para agregar a la respuesta de Ilya Palkin: incluso puede eliminar claves dinámicamente:
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};
Fuente:
_
cuál está permitido para una variable que no tiene intención de usar?
var b = {a:44, b:7, c:1}; let {['a']:z, ...others} = b; console.log(z , others ); // logs: 44, {b:7, c:1}
Para aquellos que no pueden usar ES6, pueden usar lodash
o underscore
.
_.omit(x, 'b')
O ramda
.
R.omit('b', x)
delete
.
Yo uso este ESNext 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)
Si necesita una función de propósito general:
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
puede hacer:(({b, c, ...others}) => ({...others}))(obj)
Puede escribir una función auxiliar simple para ello. Lodash tiene una función similar con el mismo nombre: omitir
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}
Además, tenga en cuenta que es más rápido que Object.assign y elimine luego: http://jsperf.com/omit-key
Tal vez algo como esto:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
¿Es esto lo suficientemente bueno? ¿O no puede c
ser copiado?
Usando la Desestructuración de Objetos
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}
_
no resuelve el problema de ESLint ...
Oye, parece que te encuentras con problemas de referencia cuando intentas copiar un objeto y luego eliminar una propiedad. En algún lugar debe asignar variables primitivas para que JavaScript cree un nuevo valor.
Truco simple (puede ser horrible) que usé fue esto
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 })));
. Ni siquiera tiene que eliminarlo, solo necesita un valor falso.
Aquí hay una opción para omitir claves dinámicas que creo que aún no se ha mencionado:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
es alias removedKey
e ignorado. newObj
se convierte { 2: 2, 3: 3, 4: 4 }
. Tenga en cuenta que la clave eliminada no existe, el valor no solo se estableció en undefined
.
LA MANERA MÁS FÁCIL
const allAlphabets = {a: 1, b: 2, c: 3, ..., z:26};
const { b, ...allExceptOne } = allAlphabets;
console.log(allExceptOne); // {a: 1, c: 3, ..., z:26}
Lodash omitir
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
También puede usar el operador de propagación para hacer esto
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 }
reduce a exactamente lo mismo.
Las soluciones anteriores que usan estructuración adolecen del hecho de que tiene una variable usada, lo que podría causar quejas de ESLint si está usando eso.
Así que aquí están mis soluciones:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
En la mayoría de las plataformas (excepto IE a menos que use Babel), también podría hacer:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
Qué tal esto:
let clone = Object.assign({}, value);
delete clone.unwantedKey;
Si se trata de una variable enorme, no desea copiarla y luego eliminarla, ya que esto sería ineficiente.
Un bucle for simple con una comprobación hasOwnProperty debería funcionar, y es mucho más adaptable a las necesidades futuras:
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
¿Qué hay de esto? Nunca encontré este patrón, pero solo estaba tratando de excluir una o más propiedades sin la necesidad de crear un objeto adicional. Esto parece hacer el trabajo, pero hay algunos efectos secundarios que no puedo ver. Por supuesto, no es muy legible.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
Lo logré de esta manera, como un ejemplo de mi reductor Redux:
const clone = { ...state };
delete clone[action.id];
return clone;
En otras palabras:
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;
- vea mi respuesta a esta pregunta.
Recientemente lo hice de esta manera muy simple:
const obj = {a: 1, b: 2, ..., z:26};
simplemente usando el operador spread para separar la propiedad no deseada:
const {b, ...rest} = obj;
... y object.assign para tomar solo la parte 'rest':
const newObj = Object.assign({}, {...rest});
rest
ya es un objeto nuevo, no necesita la última línea. Además, esto es idéntico a la solución aceptada.
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'));