如何获得一个JavaScript对象的属性的子集

说我有一个对象:

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

我想用一个属性的子集创build一个新的对象。

  // pseudo code subset = elmo.slice('color', 'height') //=> { color: 'red', height: 'unknown' } 

我怎么能做到这一点?

使用对象解构和属性速记

 const object = { a: 5, b: 6, c: 7 }; const picked = (({ a, c }) => ({ a, c }))(object); console.log(picked); // { a: 5, c: 7 } 

我build议看看Lodash ; 它有很多很好的实用function。

例如pick()就是你正在寻找的东西:

 var subset = _.pick(elmo, ['color', 'height']); 

小提琴

虽然有点冗长,但是通过使用Array.prototype.reduce ,可以实现其他人在2年前推荐的下划线/ lodash。

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

这种方法从另一方面解决它:而不是采取一个对象,并传递属性名称来提取,取一个属性名称的数组,并将其减less到一个新的对象。

虽然在最简单的情况下它更冗长,但callback在这里是非常方便的,因为你可以很容易地满足一些共同的要求,例如在新对象上将“颜色”属性更改为“颜色”,压平数组等等。当从一个服务/库接收一个对象并在另一个地方build立一个新的对象时,你需要做的事情。 虽然下划线/ lodash是优秀的,执行良好的库,这是我更less的供应商依赖的首选方法,而当我的子集构build逻辑变得更复杂时,这是一个更简单,更一致的方法。

编辑:es7版本相同:

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

没有什么像内置的核心库。

你可以写一个实用的function吗?

 var cloneAndPluck = function(sourceObject, keys) { var newObject = {}; keys.forEach(function(key) { newObject[key] = sourceObject[key]; }); return newObject; }; var subset = cloneAndPluck(elmo, ["color", "height"]); 

你也可以使用Lodash 。

 var subset = _.pick(elmo ,'color', 'height'); 

补充一下,假设你有一系列“elmo”:

 elmos = [{ color: 'red', annoying: true, height: 'unknown', meta: { one: '1', two: '2'} },{ color: 'blue', annoying: true, height: 'known', meta: { one: '1', two: '2'} },{ color: 'yellow', annoying: false, height: 'unknown', meta: { one: '1', two: '2'} } ]; 

如果你想要相同的行为,使用lodash,你只需要:

 var subsets = _.map(elmos, function(elm) { return _.pick(elm, 'color', 'height'); }); 

如果您使用的是ES6,那么使用破坏就有一个非常简洁的方法。 破坏允许您使用扩展轻松地添加到对象,但是它也允许您以相同的方式创build子对象。

 const object = { a: 'a', b: 'b', c: 'c', d: 'd', } // Remove "d" field from original object: const {d, ...partialObject} = object; console.log(partialObject) // => { a: 'a', b: 'b', c: 'c'} 

用dynamic属性解构赋值

该解决scheme不仅适用于您的具体示例,而且更普遍适用:

 const subset2 = (x, y) => ({[x]:a, [y]:b}) => ({[x]:a, [y]:b}); const subset3 = (x, y, z) => ({[x]:a, [y]:b, [z]:c}) => ({[x]:a, [y]:b, [z]:c}); // const subset4...etc. const o = {a:1, b:2, c:3, d:4, e:5}; const pickBD = subset2("b", "d"); const pickACE = subset3("a", "c", "e"); console.log( pickBD(o), // {b:2, d:4} pickACE(o) // {a:1, c:3, e:5} ); 
  1. 将参数转换为数组

  2. 使用Array.forEach()来select属性

     Object.prototype.pick = function() { var obj = {}; var args = arguments Array.from(args).forEach((k) => { obj[k]=this[k] }) return obj } var a = {0:"a",1:"b",2:"c"} var b = a.pick('1','2') //output will be {1: "b", 2: "c"} 

这在Chrome控制台中适用于我。 这有什么问题?

 var { color, height } = elmo var subelmo = { color, height } console.log(subelmo) // {color: "red", height: "unknown"} 

怎么样:

 function sliceObj(obj) { var o = {} , keys = [].slice.call(arguments, 1); for (var i=0; i<keys.length; i++) { if (keys[i] in obj) o[keys[i]] = obj[keys[i]]; } return o; } var subset = sliceObj(elmo, 'color', 'height'); 

elmo.slice会是“坏”的,因为它必须放在Object.prototype ,但是你可以这样做:

 Object.slice = function(obj, props) { var ret = {}; for(var i = 0, l = props.length; i < l; i++) { var prop = props[i]; if(obj.hasOwnProperty(prop)) { ret[prop] = obj[prop]; } } return ret; } 
 function splice() { var ret = new Object(); for(i = 1; i < arguments.length; i++) ret[arguments[i]] = arguments[0][arguments[i]]; return ret; } var answer = splice(elmo, "color", "height"); 

注意:尽pipe原来的问题是针对javascript,但可以通过下面的解决scheme来完成jQuery

你可以扩展jquery,如果你想这里是一个片的示例代码:

 jQuery.extend({ sliceMe: function(obj, str) { var returnJsonObj = null; $.each( obj, function(name, value){ alert("name: "+name+", value: "+value); if(name==str){ returnJsonObj = JSON.stringify("{"+name+":"+value+"}"); } }); return returnJsonObj; } }); var elmo = { color: 'red', annoying: true, height: 'unknown', meta: { one: '1', two: '2'} }; var temp = $.sliceMe(elmo,"color"); alert(JSON.stringify(temp)); 

这里是相同的小提琴: http : //jsfiddle.net/w633z/

只是另一种方式…

 var elmo = { color: 'red', annoying: true, height: 'unknown', meta: { one: '1', two: '2'} } var subset = [elmo].map(x => ({ color: x.color, height: x.height }))[0] 

你可以使用这个函数的对象数组= =)