Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a way to do object destructuring with …rest in Javascript where the non-rest keys are dynamic?

Say I have an object:

const obj = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" };

and I want to filter its keys to produce a smaller object. I understand I can do this:

const { key1, key2, ...rest } = obj;

And the rest variable will then be set to { key3: "value3", key4: "value4" }.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

But can a similar thing be done dynamically without key1 and key2 being hard-coded? Let’s say they are in an array unwantedKeys, whose value (["key1", "key2"]) and length can only be determined at runtime.

>Solution :

But can a similar thing be done dynamically without key1 and key2 being hard-coded? Let’s say they are in an array unwantedKeys, whose value (["key1", "key2"]) can only be determined at runtime.

Yes, but not entirely dynamically. You’d need to know how many there were. For instance, for two of them:

const { [unwantedKeys[0]]: unused1, [unwantedKeys[1]]: unused2, ...rest } = obj;
const unwantedKeys = ["key1", "key2"];
const obj = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" };
const { [unwantedKeys[0]]: unused1, [unwantedKeys[1]]: unused2, ...rest } = obj;
console.log(rest);

…which probably means it’s not useful for your situation. 🙂 (Edit: You’ve now confirmed that indeed, the length is only known at runtime.)

Since you need it to be dynamic, you can’t just do this with syntax; you can with various standard library tools, though, like:

const rest = Object.fromEntries(
    Object.entries(obj).filter(([key]) => !unwanted.includes(key))
);
const unwantedKeys = ["key1", "key2"];
const obj = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" };
const rest = Object.fromEntries(
    Object.entries(obj).filter(([key]) => !unwantedKeys.includes(key))
);
console.log(rest);

Or perhaps with a Set, if unwantedKeys is so massively long that rescanning it is a performance concern (not likely 🙂 ):

const unwantedSet = new Set(unwantedKeys);
const rest = Object.fromEntries(
    Object.entries(obj).filter(([key]) => !unwantedSet.has(key))
);
const unwantedKeys = ["key1", "key2"];
const obj = { key1: "value1", key2: "value2", key3: "value3", key4: "value4" };
const unwantedSet = new Set(unwantedKeys);
const rest = Object.fromEntries(
    Object.entries(obj).filter(([key]) => !unwantedSet.has(key))
);
console.log(rest);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading