我必须将javascript的一些字段投影到新对象。
例如,我有一个以下对象
var obj = { fn : 'Abc',
ln : 'Xyz',
id : 123,
nt : 'Note',
sl : 50000}
我想要包含fn and id
的新对象
var projectedObj = { fn : 'Abc', id : 123 }
在投影的基础上
var projection = { fn : 1, id : 1 }
像这样的东西
var projectedObj = project(obj, projection);
那么最好的方法或优化的方法是什么。
只需遍历投影对象并获取投影的键。例如
function project(obj, projection) {
let projectedObj = {}
for(let key in projection) {
projectedObj[key] = obj[key];
}
return projectedObj;
}
array#reduce
并循环访问投影对象的所有键,并根据键从原始对象中提取值并创建新对象。
var project = (o, p) => {
return Object.keys(p).reduce((r,k) => {
r[k] = o[k] || '';
return r;
},{});
}
var obj = { fn : 'Abc', ln : 'Xyz', id : 123, nt : 'Note', sl : 50000};
var projection = { fn : 1, id : 1 };
var projectedObj = project(obj, projection);
console.log(projectedObj);
您还可以将array#map
与Object#assign
一起使用来创建新对象。
var project = (o, p) => {
return Object.assign(...Object.keys(p).map(k => ({[k]: o[k]})));
}
var obj = { fn : 'Abc', ln : 'Xyz', id : 123, nt : 'Note', sl : 50000};
var projection = { fn : 1, id : 1 };
var projectedObj = project(obj, projection);
console.log(projectedObj);
您可以reduce
返回返回obj
值的projection
键:
var obj = { fn : 'Abc', ln : 'Xyz', id : 123, nt : 'Note', sl : 50000}
var projection = { fn : 1, id : 1 }
function project(obj, projection) {
return Object.keys(projection).reduce((a, e) => { a[e] = obj[e]; return a; }, {});
}
console.log(project(obj, projection));
我是这样做的。它可以处理嵌套对象,但可能无法处理可以是值或对象的属性。
let entity = {
timeStamp: "1970-01-01T00:00:00.000Z",
value: 1,
itemList: [
{
amount: 1,
product: {
name: "Product 0",
_links: { self: { href: "https://example.com:8080/api/entityA/1" } }
},
value: 1,
flag: false,
_links: { self: { href: "https://example.com:8080/api/entityB/1" } }
}
],
summerTime: false,
parent: {
grandParentA: {
name: "Grand Parent 0",
_links: { self: { href: "https://example.com:8080/api/entityC/1" } }
},
grandParentB: null,
name: "Parent 0",
_links: { self: { href: "https://example.com:8080/api/entityD/1" } }
},
_links: { self: { href: "https://example.com:8080/api/entityE/1" } }
};
let entityProjection = {
parent: {
grandParentA: {
_links: { self: { href: false } }
},
grandParentB: {
_links: { self: { href: false } }
},
_links: { self: { href: false } }
},
_links: { self: { href: false } }
}
const project = (object, projection) => {
return Object.keys(projection).reduce((a, e) => ({ ...a, [e]: object[e] ? (projection[e] ? project(object[e], projection[e]) : object[e]) : object[e] }), {});
}
console.log(project(entity, entityProjection));
作为不传入投影对象而是将要投影的属性列为逗号分隔字符串的替代方法,此模块可以做到这一点。请注意,此模块支持的不是对象,而是数组。
var linqmodule = (function() {
projection = function(members) {
var membersArray = members.replace(/s/g, "").split(",");
var projectedObj = {};
for (var i = 0; i < this.length; i++) {
for (var j = 0; j < membersArray.length; j++) {
var key = membersArray[j];
if (j === 0) {
projectedObj[i] = {};
}
projectedObj[i][key] = this[i][key];
}
}
return projectedObj;
};
Array.prototype.select = projection;
dumpmethod = function(arrayobj) {
var result = "";
result += "[";
for (var i = 0; i < Object.keys(arrayobj).length; i++) {
var membersArray = Object.keys(arrayobj[i]);
for (var j = 0; j < membersArray.length; j++) {
if (j === 0) {
result += "{";
}
var key = membersArray[j];
result +=
"key: " +
key +
" , value: " +
arrayobj[i][key] +
(j < membersArray.length - 1 ? " , " : "");
if (j === membersArray.length - 1) {
result +=
"}" + (i < Object.keys(arrayobj).length - 1 ? "," : "") + "n";
}
}
}
result += "]";
return result;
};
return {
dump: dumpmethod
};
})();
若要投影 Json 对象数组,可以使用此示例作为指南:
var someCountries = [
{ country: "Norway", population: 5.2, code: "NO" },
{ country: "Finland", population: 5.5, code: "SU" },
{ country: "Iceland", population: 0.4, code: "IC" },
{ country: "Sweden", population: 10.2, code: "SW" }
];
var result = someNums.select("country,population");
console.log(linqmodule.dump(result));
然后,生成的数组包含投影结果(并复制到新数组中(,而不使用字段"code"。
这并没有回答这个问题,因为它询问了单个对象和一个投影对象,但它展示了如何使用对象数组(在数组的每个对象中具有相同的字段(实现相同的目标。然后,许多人会发现它对类似的场景很有用。