如何获得一个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} );
-
将参数转换为数组
-
使用
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]
你可以使用这个函数的对象数组= =)