Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing targeted parameter from Object in ES6 using spread operator

Tags:

I am trying to remove a property from an object using the spread operator. Traditionally I have done this:

const original_object = { prop1 : 'string1', prop2: 'string2' };
const { prop1, ...rest } = original_object;

In the above situation, the removed property(prop1) will no longer exist within the rest object.

Suppose there is a more intricate property that I would like to remove, such as an object within the object.

const original_object = {
    prop1: 'string1'
    prop2: {
        prop3: 'string3',
        prop4: 'string4'
    }
}
const { *remove prop3 of prop2 only here*, ...rest} = original_object;
console.log(prop3); // => 'string3';

What is the most elegant/easiest solution to do this? I want everything but the one prop3 of prop2 to be included in the object, in the exact same structure.

like image 768
shn Avatar asked Jun 12 '19 23:06

shn


1 Answers

Do it in two steps - first destructure the prop3 out, then create a new object, combining the rest of the outer object with the prop2 with the prop3 removed from it:

const original_object = {
    prop1: 'string1',
    prop2: {
        prop3: 'string3',
        prop4: 'string4'
    }
};
const { prop2: { prop3, ...restProp2 }, ...restOrig} = original_object;
const newObj = { ...restOrig, prop2: restProp2 };
console.log(prop3); // => 'string3';
console.log(newObj);

While you could do this in just one statement with a hack, I wouldn't recommend it.

If you find yourself doing this often with deeply nested properties, and don't like the extra line, maybe consider a helper function along the lines of:

const getNestedFrom = (obj, propStr) => {
  // make a copy, don't mutate the original object
  const newObj = JSON.parse(JSON.stringify(obj));
  const props = propStr.split('.');
  const lastProp = props.pop();
  const lastObj = props.reduce((a, prop) => a[prop], newObj);
  const val = lastObj[lastProp];
  delete lastObj[lastProp];
  return [newObj, val];
};


const original_object = {
    prop1: 'string1',
    prop2: {
        prop3: 'string3',
        prop4: 'string4'
    }
};
const [newObj, prop3] = getNestedFrom(original_object, 'prop2.prop3');
console.log(prop3); // => 'string3';
console.log(newObj);

Just for curiosity's sake (please don't do this), the hack would be to use a default property which definitely won't exist:

const original_object = {
    prop1: 'string1',
    prop2: {
        prop3: 'string3',
        prop4: 'string4'
    }
};
const [
  { prop2: { prop3, ...restProp2 }, ...restOrig},
  newObj = { ...restOrig, prop2: restProp2 }
] = [original_object]
console.log(prop3); // => 'string3';
console.log(newObj);

But that would be significantly (and needlessly) confusing.

like image 170
CertainPerformance Avatar answered Sep 19 '22 22:09

CertainPerformance