jrothafer
jrothafer

Reputation: 169

Filtering Javascript object using array of keys

Basically, I have JavaScript array that looks like this:

var keyFilters = ["key_1", "key_2", "key_3"];

And I have an object that looks like this:

myObject["key_1"] = "Value 1";
myObject["key_2"] = "Value 2";
myObject["key_random"] = "Value 2";

I need to pair down my myObject object to only have the keys that exists in the keyFilters array. Sometimes, the object won't have a key that exists in the filter. In this example, filtering myObject against keyFilters would result in this outputted object:

myObject = {
    "key_1": "Value 1",
    "key_2": "Value 2",
}

I know there is no map function for objects in JS, but there is one for arrays. Would it be best to use that or just write a single-off function for iterating over the array and then over the object, and push to a new object that only has the matching keys, or is there some slicker way?

Upvotes: 0

Views: 2504

Answers (5)

vol7ron
vol7ron

Reputation: 42099

Iterate over the Object's keys, then look for the key in your array using includes method, if it doesn't exist, then delete it.

var safe_keys = ["key_1", "key_2", "key_3"],
  obj = {
    'key_1': 'Value 1',
    'key_2': 'Value 2',
    'key_random': 'Value 2'
  };

for (let key of Object.keys(obj))
  !safe_keys.includes(key) && delete obj[key];

console.log(obj);

Upvotes: 0

Samuli Hakoniemi
Samuli Hakoniemi

Reputation: 19049

If you want to return a new object based on your data, then use this:

let keyFilters = ["key_1", "key_2", "key_3"];
let myObject = {};
myObject["key_1"] = "Value 1";
myObject["key_2"] = "Value 2";
myObject["key_random"] = "Value 2";

let newObject = Object.keys(myObject)
.filter((key) => keyFilters.includes(key))
.map((key) => {
  return {[key]: myObject[key]}
})
.reduce((a, b) => Object.assign({}, a,b));

It:

1) filters only the keys (as an array) which are included

2) maps through them and creates new objects (as an array) of key-value pairs

3) reduces the mapped array to a single object

Upvotes: 1

nerestaren
nerestaren

Reputation: 166

I know there is no map function for objects in JS, but there is one for arrays. Would it be best to use that or just write a single-off function for iterating over the array and then over the object, and push to a new object that only has the matching keys, or is there some slicker way?

True, but you can map an Object's keys:

Object.keys(myObject).map(key => {
  if (keyFilters.indexOf(key) === -1) {
    delete myObject[key];
  }
});

I hope this suits you!

Upvotes: 0

Brad
Brad

Reputation: 163272

Underscore.js has a pretty good implementation. https://github.com/jashkenas/underscore/blob/master/underscore.js#L1108

  // Return a copy of the object only containing the whitelisted properties.
  _.pick = restArgs(function(obj, keys) {
    var result = {}, iteratee = keys[0];
    if (obj == null) return result;
    if (_.isFunction(iteratee)) {
      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
      keys = _.allKeys(obj);
    } else {
      iteratee = keyInObj;
      keys = flatten(keys, false, false);
      obj = Object(obj);
    }
    for (var i = 0, length = keys.length; i < length; i++) {
      var key = keys[i];
      var value = obj[key];
      if (iteratee(value, key, obj)) result[key] = value;
    }
    return result;
  });

Upvotes: 0

Kosh
Kosh

Reputation: 18378

for (i in myObject) if (keyFilters.indexOf(i) < 0) delete myObject[i];

Upvotes: 3

Related Questions