I have a flat JS object:
{a: 1, b: 2, c: 3, ..., z:26}
I want to clone the object except for one element:
{a: 1, c: 3, ..., z:26}
What's the easiest way to do this (preferring to use es6/7 if possible)?
I have a flat JS object:
{a: 1, b: 2, c: 3, ..., z:26}
I want to clone the object except for one element:
{a: 1, c: 3, ..., z:26}
What's the easiest way to do this (preferring to use es6/7 if possible)?
There is a Destructuring assignment syntax in JavaScript that can be used
let obj = {a: 1, b: 2, c: 3, z:26};
let {b, ...rest} = obj;
// skips the "Unused variable" warning
let {b: _, ...rest} = obj;
// removes property based on the dynamic key
const dynamicKey = "b";
let {[dynamicKey]: _, ...rest} = obj;
Modern browsers already support it out of the box. See: JavaScript operator: Destructuring assignment: Rest in objects
For old browser versions there is an option to use Babel to support destructuring assignment. It will be transpiled into:
"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}];
–
Inapt let y = x.map(item => { /* remove one key from the item and return it */ })
–
Mendelson ignoreRestSiblings
that was added in v3.15.0 (February 3, 2017). See: commit c59a0ba –
Mendelson b
in scope. –
Hushaby x
contained an object property, and since an object is a reference (codeburst.io/…), you could by mistake modify a nested value inside of x
while modifying it in y
. –
Lympho bName
- is the name of subject key - this does not work: let {[bName], ...y} = x;
I am uninstalling node right now, it not capable of doing just what we want!!!!1111 (that was oneliner, one function) –
Uund let y = {...x}; delete y.b;
–
Rowan let { b: _b, ...y } = x;
to skip the "Unused variable" warning. –
Hokanson const { [dynamicKey]: _, ...rest } = obj;
–
Biome I use this 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)
map
you can do: (({b, c, ...others}) => ({...others}))(obj)
–
Nickname _.omit(obj, ['b', 'c'])
. –
Smoke omit({}, "}));alert('gotcha!')(({a")
–
Rochelle const { b, c, ...clone } = obj
? –
Archiearchiepiscopacy b
and c
do not stay assigned (or reassigned) in the current scope. A comment on the accepted answer mentioned that linters may even complain about that, if the variables are unused. –
Flavius var clone = Object.assign({}, {a: 1, b: 2, c: 3});
delete clone.b;
or if you accept property to be undefined:
var clone = Object.assign({}, {a: 1, b: 2, c: 3}, {b: undefined});
For those who can't use ES6, you can use lodash
or underscore
.
_.omit(x, 'b')
Or ramda
.
R.omit('b', x)
_.omit(x, 'b')
–
Shakira delete
. –
Libertinage To add to Ilya Palkin's answer: you can even dynamically remove keys:
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};
Source:
_
which is allowed for a variable that you don't intend to use? –
Blastoderm var b = {a:44, b:7, c:1}; let {['a']:z, ...others} = b; console.log(z , others ); // logs: 44, {b:7, c:1}
–
Libertinage You can write a simple helper function for it. Lodash has a similar function with the same name: omit
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}
Also, note that it is faster than Object.assign and delete then: http://jsperf.com/omit-key
Object.keys(obj).filter(key => key != omitKey).reduce((result, key) => ({...result, [key]: obj[key]}), {});
–
Ochlocracy omitKeys.includes(key)
on every iteration instead of just once at the end –
Aviary Here's an option for omitting dynamic keys that I believe has not been mentioned yet:
const obj = { 1: 1, 2: 2, 3: 3, 4: 4 };
const removeMe = 1;
const { [removeMe]: removedKey, ...newObj } = obj;
removeMe
is aliased as removedKey
and ignored. newObj
becomes { 2: 2, 3: 3, 4: 4 }
. Note that the removed key does not exist, the value was not just set to undefined
.
Maybe something like this:
var copy = Object.assign({}, {a: 1, b: 2, c: 3})
delete copy.c;
Is this good enough? Or can't c
actually get copied?
Using Object Destructuring
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}
_
doesn't solve the issue for ESLint... –
Isotone "no-unused-vars": ["error", { "args": "all", "argsIgnorePattern": "^_" } ]
. –
Strongminded I am using object destructuring here. I have separated the password into variables and the rest variables contain all object properties and values except the password. NOTE: rest is not fixed keyword here you can name it accordingly
const obj = {name:"john", password:"Abcds12@", id:"125455"}
const {password,...rest} = obj;
console.log(rest);
Hey seems like you run in to reference issues when you're trying to copy an object then deleting a property. Somewhere you have to assign primitive variables so javascript makes a new value.
Simple trick (may be horrendous) I used was this
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 })));
. Don't even have to delete it, just needs a falsy value. –
Meitner You also can use spread operator to do this
const source = { a: 1, b: 2, c: 3, z: 26 }
const copy = { ...source, ...{ b: undefined } } // { a: 1, c: 3, z: 26 }
copy
–
Burtburta const copy = { ...source, b: undefined }
boils down to exactly the same. –
Isotone Object.keys(copy)
would still return ['a', 'b', 'c', 'z']
which is not always what you want. –
Wondrous What about this? I never found this patter around but I was just trying to exclude one or more properties without the need of creating an extra object. This seems to do the job but there are some side effects I'm not able to see. For sure is not very readable.
const postData = {
token: 'secret-token',
publicKey: 'public is safe',
somethingElse: true,
};
const a = {
...(({token, ...rest} = postData) => (rest))(),
}
/**
a: {
publicKey: 'public is safe',
somethingElse: true,
}
*/
The solutions above using structuring do suffer from the fact that you have an used variable, which might cause complaints from ESLint if you're using that.
So here are my solutions:
const src = { a: 1, b: 2 }
const result = Object.keys(src)
.reduce((acc, k) => k === 'b' ? acc : { ...acc, [k]: src[k] }, {})
On most platforms (except IE unless using Babel), you could also do:
const src = { a: 1, b: 2 }
const result = Object.fromEntries(
Object.entries(src).filter(k => k !== 'b'))
Lodash omit
let source = //{a: 1, b: 2, c: 3, ..., z:26}
let copySansProperty = _.omit(source, 'b');
// {a: 1, c: 3, ..., z:26}
I accomplished it this way, as an example from my Redux reducer:
const clone = { ...state };
delete clone[action.id];
return clone;
In other words:
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;
- see my answer on this question. –
Justiciable 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'));
If you're dealing with a huge variable, you don't want to copy it and then delete it, as this would be inefficient.
A simple for-loop with a hasOwnProperty check should work, and it is much more adaptable to future needs :
for(var key in someObject) {
if(someObject.hasOwnProperty(key) && key != 'undesiredkey') {
copyOfObject[key] = someObject[key];
}
}
I don't know exactly what you want to use this for, so I'm not sure if this would work for you, but I just did the following and it worked for my use case:
const newObj ={...obj, [key]: undefined}
[key]
property with value = undefined
. This is different than object not having the [key]
property. E.g. Object.keys()
will give you different results on these objects. –
Esther The delete keyword solution will throw a compilation error if you're using typescript, because it breaks the contract of the object you instantiated. And the ES6 spread operator solution (const {x, ...keys} = object
) may throw an error depending on the linting configuration you're using on your project, since the x
variable is not beign used. So I came up with this solution:
const cloneObject = Object.entries(originalObject)
.filter(entry => entry[0] !== 'keyToRemove')
.reduce((acc, keyValueTuple) => ({ ...acc, [keyValueTuple[0]]: keyValueTuple[1] }), {});
It solves the problem using the combination of Object.entries method (to get an array of key/value pairs of the original object) and the array methods filter and reduce. It looks verbose, but I think it's nice to have a one line chainable solution.
Here are my two cents, on Typescript, slightly derived from @Paul's answer and using reduce instead.
function objectWithoutKey(object: object, keys: string[]) {
return keys.reduce((previousValue, currentValue) => {
// @ts-ignore
const {[currentValue]: undefined, ...clean} = previousValue;
return clean
}, object)
}
// usage
console.log(objectWithoutKey({a: 1, b: 2, c: 3}, ['a', 'b']))
I have one object named: options with some keys
let options = {
userDn: 'somePropertyValue',
username: 'someValue',
userSearchBase: 'someValue',
usernameAttribute: 'uid',
userPassword: 'someValue'
}
I want to log all object excelp userPassword Property because Im testing something, I am using this code:
console.log(Object.keys(options).map(x => x + ': ' + (x === "userPassword" ? '---' : options[x])));
If you want to make it dynamic, just make a function and instead of explicitly putting userPassword you can place the value of the property you want to exclude
Clean and fast using lodash, With this solution, you are able to remove multiple keys and also without changing the original object. This is more extendable and more usable in different situations:
import * as _ from 'lodash';
function cloneAndRemove(
removeTheseKeys: string[],
cloneObject: any,
): object | never {
const temp = _.cloneDeep(cloneObject);
removeTheseKeys.forEach((key) => {
delete temp[key];
});
return temp;
}
export { cloneAndRemove };
Here is a Typescript method to do that. Expects 2 arguments, the object and an array of strings containing keys to be removed:
removeKeys(object: { [key: string]: any }, keys: string[]): { [key: string]: any } {
const ret: { [key: string]: any } = {};
for (const key in object) {
if (!keys.includes(key)) {
ret[key] = object[key];
}
}
return ret;
}
You can use lodash library for this purpose (definitely if you need to work with lots of arrays/array of objects/objects in a project).
Using lodash deepclone function You can do:
const _obj = _.cloneDeep(obj);
delete _obj.key;
First clones the whole object into new object and then delete the desired key from the cloned object so that the original one doesn't get affected.
© 2022 - 2024 — McMap. All rights reserved.
structuredClone
fallbacking toJSON.parse(JSON.stringify
method – Torgerson