How to get a subset of a javascript object's properties

后端 未结 27 2221
刺人心
刺人心 2020-11-21 22:46

Say I have an object:

elmo = { 
  color: \'red\',
  annoying: true,
  height: \'unknown\',
  meta: { one: \'1\', two: \'2\'}
};

I want to m

27条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-11-21 23:27

    While it's a bit more verbose, you can accomplish what everyone else was recommending underscore/lodash for 2 years ago, by using Array.prototype.reduce.

    var subset = ['color', 'height'].reduce(function(o, k) { o[k] = elmo[k]; return o; }, {});
    

    This approach solves it from the other side: rather than take an object and pass property names to it to extract, take an array of property names and reduce them into a new object.

    While it's more verbose in the simplest case, a callback here is pretty handy, since you can easily meet some common requirements, e.g. change the 'color' property to 'colour' on the new object, flatten arrays, etc. -- any of the things you need to do when receiving an object from one service/library and building a new object needed somewhere else. While underscore/lodash are excellent, well-implemented libs, this is my preferred approach for less vendor-reliance, and a simpler, more consistent approach when my subset-building logic gets more complex.

    edit: es7 version of the same:

    const subset = ['color', 'height'].reduce((a, e) => (a[e] = elmo[e], a), {});
    

    edit: A nice example for currying, too! Have a 'pick' function return another function.

    const pick = (...props) => o => props.reduce((a, e) => ({ ...a, [e]: o[e] }), {});
    

    The above is pretty close to the other method, except it lets you build a 'picker' on the fly. e.g.

    pick('color', 'height')(elmo);
    

    What's especially neat about this approach, is you can easily pass in the chosen 'picks' into anything that takes a function, e.g. Array#map:

    [elmo, grover, bigBird].map(pick('color', 'height'));
    // [
    //   { color: 'red', height: 'short' },
    //   { color: 'blue', height: 'medium' },
    //   { color: 'yellow', height: 'tall' },
    // ]
    

提交回复
热议问题