0

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?

jrothafer
  • 169
  • 1
  • 9
  • You suggestion about the function that creates a new object is fine (and probably the best way). – ibrahim mahrir Jun 13 '17 at 00:50
  • Thanks. This may be way a way misguided thought but I want to do everything I can to reduce memory usage in this over-complicated front-end JS app I inherited, including not introducing new objects when I could pair down an already instantiated object. – jrothafer Jun 13 '17 at 00:52
  • you can have a look at http://underscorejs.org/#mapObject – Jin Jun 13 '17 at 00:53
  • 1
    Does this answer your question? [Filter object properties by key in ES6](https://stackoverflow.com/questions/38750705/filter-object-properties-by-key-in-es6) – user202729 Feb 16 '21 at 10:19

5 Answers5

3
for (i in myObject) if (keyFilters.indexOf(i) < 0) delete myObject[i];
Kosh
  • 16,966
  • 2
  • 19
  • 34
1

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

Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
0

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;
  });
Brad
  • 159,648
  • 54
  • 349
  • 530
0

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!

nerestaren
  • 156
  • 1
  • 12
0

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);
vol7ron
  • 40,809
  • 21
  • 119
  • 172