Javascript 如何找到项目的总和并动态创建新对象?
如何根据以下数据对类似于目标对象的对象进行建模?如果ES6中存在任何缩写,那么它将更合适 数据示例包含人员及其收集的项目的信息。people Max和Carol收集了具有不同值的相同石头。如果发生这种情况,应将其作为新项目推送到目标对象中 样本数据Javascript 如何找到项目的总和并动态创建新对象?,javascript,object,ecmascript-6,Javascript,Object,Ecmascript 6,如何根据以下数据对类似于目标对象的对象进行建模?如果ES6中存在任何缩写,那么它将更合适 数据示例包含人员及其收集的项目的信息。people Max和Carol收集了具有不同值的相同石头。如果发生这种情况,应将其作为新项目推送到目标对象中 样本数据 let people = [{ "id": 1, // Person Id "name": "John", // Name of person "date":
let people = [{
"id": 1, // Person Id
"name": "John", // Name of person
"date": "2017-5-27", // Date
"totalAssets": 500, // Sum of total (gems collected)
"gems": [{ // Gems collected from forest
"total": 500, // totalCollected * value
"value": 100, // Value of one gem (Ruby = 100)
"totalCollected": 5, // Total number
"gemName": "Ruby", // Gem name
"gemCode": "GEM001" // Gem code
}]
}, {
"id": 2,
"name": "Max",
"date": "2017-5-28",
"totalAssets": 1300, // TotalAssets = Emerald.total + Moonstone.total
"gems": [{
"total": 900,
"value": 150,
"totalCollected": 6,
"gemName": "Emerald",
"gemCode": "GEM002"
}, {
"total": 400,
"value": 250,
"totalCollected": 2,
"gemName": "Moonstone",
"gemCode": "GEM003"
}]
}, {
"id": 3,
"name": "Carol",
"date": "2017-5-29",
"totalAssets": 2900,
"gems": [{
"total": 1500,
"value": 150,
"totalCollected": 10,
"gemName": "Emerald",
"gemCode": "GEM002"
}, {
"total": 1000,
"value": 200,
"totalCollected": 5,
"gemName": "Moonstone",
"gemCode": "GEM003"
},
{
"total": 400,
"value": 100,
"totalCollected": 4,
"gemName": "Ruby",
"gemCode": "GEM001"
}
]
}]
计算总数
computeTotal = () => { //Mock target object function
// Return target object
"totalAssets": 4800, //Total assets of all people
"gemsValueTotal":[{
"gemName": "Ruby",
"value": 100,
"totalC0llected":9,
"total": 900,
},
{
"gemName": "Emerald",
"value": 150,
"totalC0llected":16,
"total": 2400,
},
{
"gemName": "MoonStone",
"value": 200,
"totalC0llected":5,
"total": 1000,
},
{
"gemName": "MoonStone", // Value changed so push as new item in object
"value": 250,
"totalC0llected":2,
"total": 500,
}
]
}
我以这种方式找到了一些解决办法
aggregateGems(data) {
this.rows = [];
let totalCollected = 0;
let totalvalue = 0;
return data.filter((item) => {
item.gems.map(d => {
let model: any = {};
let totalAssets: number = 0;
totalCollected += parseInt(d.totalCollected);
totalvalue += parseInt(d.total);
model.gemname = d.gemName;
model.value = d.value;
model.totalCollected = totalCollected;
model.totalValue = totalValue;
this.rows.push(model);
debugger
});
},
);
}
您可以使用该函数,并与该函数配合使用
// this will save the indexes of the gemNames and value in the output array (so you don't have to search for the index all of the time)
let gemNameValueIndex = {};
// this will reduce the people array in a new object, receiving the new object and the next person on each iteration
let totals = people.reduce( (current, person) => {
// and for each person we need to iterate the gems
person.gems.forEach( gem => {
// each gem increases the total value
current.totalAssets += gem.total;
let key = gem.gemName + gem.value;
let idx;
if ((idx = gemNameValueIndex[key]) === undefined) {
// no matching gem found, so add the index
current.gemsValueTotal.push( {
gemName: gem.gemName,
value: gem.value,
totalCollected: gem.totalCollected,
total: gem.total
} );
// mark the index so it can be looked up for next iterations
gemNameValueIndex[key] = current.gemsValueTotal.length - 1;
return;
}
// update the already found index with the new totals
current.gemsValueTotal[idx].totalCollected += gem.totalCollected;
current.gemsValueTotal[idx].total += gem.total;
});
return current;
}, { totalAssets: 0, gemsValueTotal: [] } );
您的totals
对象现在将包含您正在查找的数据(您可以在下面的代码段中进行尝试)
gemNameValueIndex
将包含每个值的gems作为一个键,并在生成的total对象中包含索引(但该对象仅用于避免在gemnameValueTotal中循环所有添加的gems,以根据gemName和每个gem的值查找索引,我们需要进行比较)
let people=[{
“id”:1,//个人id
“姓名”:“John”,//姓名
“日期”:“2017-5-27”,//日期
“totalAssets”:500,//总计(收集的宝石)
“宝石”:[{//从森林中收集的宝石
“总计”:500,//totalCollected*值
“值”:100,//一颗宝石的值(Ruby=100)
“totalCollected”:5,//总数
“gemName”:“Ruby”,//Gem name
“gemCode”:“GEM001”//Gem代码
}]
}, {
“id”:2,
“名称”:“最大值”,
“日期”:“2017-5-28”,
“totalAssets”:1300,//totalAssets=Emerald.total+Moonstone.total
“宝石”:[{
“总数”:900,
“价值”:150,
“总计收集”:6,
“宝石名”:“翡翠”,
“gemCode”:“GEM002”
}, {
“总数”:400,
“价值”:250,
“总计收集”:2,
“gemName”:“月光石”,
“gemCode”:“GEM003”
}]
}, {
“id”:3,
“姓名”:“卡罗尔”,
“日期”:“2017-5-29”,
“总资产”:2900,
“宝石”:[{
“总数”:1 500,
“价值”:150,
“总计收集”:10,
“宝石名”:“翡翠”,
“gemCode”:“GEM002”
}, {
“总数”:1000,
“价值”:200,
“总计收集”:5,
“gemName”:“月光石”,
“gemCode”:“GEM003”
},
{
“总数”:400,
“价值”:100,
“总计收集”:4,
“gemName”:“Ruby”,
“gemCode”:“GEM001”
}
]
}];
//这将在输出数组中保存gemNames和value的索引(因此您不必一直搜索索引)
让gemNameValueIndex={};
//这将减少新对象中的人员数组,在每次迭代中接收新对象和下一个人
让总数=人。减少((当前,人)=>{
//对于每个人,我们需要迭代这些宝石
person.gems.forEach(gem=>{
//每颗宝石都会增加总价值
流动资产总额+=创业板总额;
让key=gem.gemName+gem.value;
让idx;
if((idx=gemNameValueIndex[key])==未定义){
//找不到匹配的gem,请添加索引
当前.gemsValueTotal.push({
gemName:gem.gemName,
价值:gem.value,
totalCollected:gem.totalCollected,
总数:gem.total
} );
//标记索引,以便在下一次迭代中查找它
gemNameValueIndex[键]=current.gemValueTotal.length-1;
回来
}
//用新总数更新已找到的索引
current.gemValueTotal[idx].totalCollected+=gem.totalCollected;
当前.gemValueTotal[idx].total+=gem.total;
});
回流;
},{totalAssets:0,GemValueTotal:[]});
控制台日志(总计)代码>你试过什么吗?@31piy谢谢你的回复。请查看更新的。谢谢。这正是我想要的。