Filter object properties by key in ES6

If you have a list of allowed values, you can easily retain them in an object using:

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    obj[key] = raw[key];
    return obj;
  }, {});

console.log(filtered);

This uses:

  1. Object.keys to list all properties in raw (the original data), then
  2. Array.prototype.filter to select keys that are present in the allowed list, using
    1. Array.prototype.includes to make sure they are present
  3. Array.prototype.reduce to build a new object with only the allowed properties.

This will make a shallow copy with the allowed properties (but won't copy the properties themselves).

You can also use the object spread operator to create a series of objects without mutating them (thanks to rjerue for mentioning this):

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

const filtered = Object.keys(raw)
  .filter(key => allowed.includes(key))
  .reduce((obj, key) => {
    return {
      ...obj,
      [key]: raw[key]
    };
  }, {});

console.log(filtered);

For purposes of trivia, if you wanted to remove the unwanted fields from the original data (which I would not recommend doing, since it involves some ugly mutations), you could invert the includes check like so:

const raw = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const allowed = ['item1', 'item3'];

Object.keys(raw)
  .filter(key => !allowed.includes(key))
  .forEach(key => delete raw[key]);

console.log(raw);

I'm including this example to show a mutation-based solution, but I don't suggest using it.


If you are OK with using ES6 syntax, I find that the cleanest way to do this, as noted here and here is:

const data = {
  item1: { key: 'sdfd', value:'sdfd' },
  item2: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

const { item2, ...newData } = data;

Now, newData contains:

{
  item1: { key: 'sdfd', value:'sdfd' },
  item3: { key: 'sdfd', value:'sdfd' }
};

Or, if you have the key stored as a string:

const key = 'item2';
const { [key]: _, ...newData } = data;

In the latter case, [key] is converted to item2 but since you are using a const assignment, you need to specify a name for the assignment. _ represents a throw away value.

More generally:

const { item2, ...newData } = data; // Assign item2 to item2
const { item2: someVarName, ...newData } = data; // Assign item2 to someVarName
const { item2: _, ...newData } = data; // Assign item2 to _
const { ['item2']: _, ...newData } = data; // Convert string to key first, ...

Not only does this reduce your operation to a one-liner but it also doesn't require you to know what the other keys are (those that you want to preserve).

A simple utility function would look like this:

function removePropFromObject(obj, prop) {
  const { [prop]: _, ...rest } = obj
  return { ...rest }
}