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 do this with syntax alone; but you can with various standard library tools, like Object.entries
, Array.prototype.filter
, and Object.fromEntries
:
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);