Reputation: 733
I would like to delete a property and return a new object without mutating the original object.
I know we can do this easily with Lodash like this:
const profile = { name: 'Maria', age: 30 }
_.omit(profile, name) // it returns a new object without the property name {age: 30}
However, I would like to know if it's possible to do it with vanilla JavaScript without assigning that value to undefined
or using a filter
?
Upvotes: 20
Views: 17068
Reputation: 133
Slight variation of the accepted answer that just uses rest params:
const omit = (o, ...paths) =>
Object.fromEntries(Object.entries(o).filter(([k]) => !paths.includes(k)))
Upvotes: 0
Reputation: 31
you can try this.
export const flattenKeys = (s) =>
s
.replace(/\[(\w+)\]/g, '.$1')
.replace(/^\./, '')
.split('.');
export const omit = (object, path) => {
const obj = object;
let keys = path;
if (typeof keys === 'string') {
keys = flattenKeys(keys);
}
if (keys.length === 1) {
delete obj[keys];
return undefined;
}
return omit(obj[keys[0]], keys.slice(1).join('.'));
};
Example:
const data = {
user: {
name: 'Khoa',
age: 24
},
company: {
name: 'Test',
}
}
omit(data, 'company.name')
// output:
// { user: { name: 'Khoa', age: 24 }, company: {} }
Upvotes: 3
Reputation: 101
const obj = {
prop0: 0,
prop1: 1,
prop2: 2,
prop3: 3,
};
const prunedObj = (({ prop1, prop2, ...rest }) => rest)(obj);
// prunedObj => { prop0: 0, prop3: 3}
Upvotes: 10
Reputation: 2320
wrote a package just to solve this issue
https://www.npmjs.com/package/fp-omit
it doesn't mutate or uses delete
under the hood, but pure functional rambda function
Upvotes: 0
Reputation: 191986
For a single key you can destructure the object, and use computed property with rest to create an object without the property:
const omitSingle = (key, { [key]: _, ...obj }) => obj
const profile = { name: 'Maria', age: 30 }
const result = omitSingle('name', profile)
console.log(result)
To omit multiple properties, you can convert the object to [key, value] pairs, filter the pairs according to the listed keys array, and then convert back to an object via Object.fromEntries()
:
const omit = (keys, obj) =>
Object.fromEntries(
Object.entries(obj)
.filter(([k]) => !keys.includes(k))
)
const profile = { name: 'Maria', gender: 'Female', age: 30 }
const result = omit(['name', 'gender'], profile)
console.log(result)
Upvotes: 32
Reputation: 855
If you don't have a nested object, try to clone as follows:
const profile = { name: 'Maria', age: 30 }
function deleteProperty(object, property){
var clonedObject = JSON.parse(JSON.stringify(object));
delete clonedObject[property];
return clonedObject;
}
var newProfile = deleteProperty(profile, "name");
console.log(profile);
console.log(newProfile);
Upvotes: 1