![](/img/trans.png)
[英]How to add the key with value for each object inside an array of objects?
[英]Aggregate an object in which the value for each key is an array of objects
我正在使用 Underscore 和 Lodash 按日期对数组进行分组。 到目前为止,一切正常,我得到了一个 object,其中每个键的值都是一个对象数组,如下所示:
{
"april": [
{
"quantity": "200",
"date": "05/04/2020, 23:43",
"price": "150",
"product": "Washing Machine",
"provider": "LG",
"total": 30000
},
{
"quantity": "1000",
"date": "10/04/2020, 00:35",
"price": "800",
"product": "Television",
"provider": "Samsung",
"total": 800000
},
{
"quantity": "3000",
"date": "10/04/2020, 18:02",
"price": "2",
"product": "Computer",
"provider": "Sony",
"total": 600000
},
{
"quantity": "1000",
"date": "10/04/2020, 18:03",
"price": "300",
"product": "Bluetooth Speaker",
"provider": "Sony",
"total": 300000
}
],
"march": [
{
"quantity": "400",
"date": "18/03/2020, 23:47",
"price": "230",
"product": "Home Theatre",
"provider": "Bose",
"total": 92000
}
],
"february": [
{
"quantity": "550",
"date": "07/02/2020, 23:52",
"price": "300",
"product": "Printer",
"provider": "Epson",
"total": 165000
},
{
"quantity": "750",
"date": "07/02/2020, 23:52",
"price": "200",
"product": "Television",
"provider": "Panasonic",
"total": 150000
}
]
}
我想知道谁是每个月最大的供应商(例如,4 月份是索尼,两次不同的采购总额为 900,000 美元),但我一直在尝试访问和汇总数据。 我知道 Stackoverflow 中有很多类似的问题,但令人惊讶的是,我无法找到任何与这种数据结构类似的问题。 任何帮助将不胜感激。
您可以结合map()
和reduce()
来实现您正在寻找的东西,例如:
let data = { april: [{ quantity: "200", date: "05/04/2020, 23:43", price: "150", product: "Washing Machine", provider: "LG", total: 30000, }, { quantity: "1000", date: "10/04/2020, 00:35", price: "800", product: "Television", provider: "Samsung", total: 800000, }, { quantity: "3000", date: "10/04/2020, 18:02", price: "2", product: "Computer", provider: "Sony", total: 600000, }, { quantity: "1000", date: "10/04/2020, 18:03", price: "300", product: "Bluetooth Speaker", provider: "Sony", total: 300000, }, ], march: [{ quantity: "400", date: "18/03/2020, 23:47", price: "230", product: "Home Theatre", provider: "Bose", total: 92000, }, ], february: [{ quantity: "550", date: "07/02/2020, 23:52", price: "300", product: "Printer", provider: "Epson", total: 165000, }, { quantity: "750", date: "07/02/2020, 23:52", price: "200", product: "Television", provider: "Panasonic", total: 150000, }, ], }; let aggregatedData = Object.keys(data).map((month) => data[month].reduce((acc, current, i) => { let existing = acc.find((o) => o.provider === current.provider); if (existing) { existing.total += current.total; } else { acc[i] = { provider: current.provider, total: current.total }; } return acc; }, []) ); let biggestProviders = aggregatedData.map((data) => data.reduce((p, c) => (c.total > p.total? c: p)) ); console.log(biggestProviders); console.log(biggestProviders.map(o => o.provider));
根据数据的键,我们获取每个月的公司数据数组并减少对象,如果提供者已经存在,则累积它们的总数。 然后我们 map 并通过比较哪一个具有最高的总数来减少结果数据,然后我们只是 map 最终结果得到提供者的名称。
边缘案例:我还注意到这种方法的一个小问题,即在有两个提供者总数完全相同的情况下,所以我制作了一个快速片段,它将只返回一个 arrays 提供者数组恰好有相同的总数。 如果我们不考虑这一点,我们可能只会返回最大的提供商之一:
let data = { april: [{ quantity: "200", date: "05/04/2020, 23:43", price: "150", product: "Washing Machine", provider: "LG", total: 30000, }, { quantity: "1000", date: "10/04/2020, 00:35", price: "800", product: "Television", provider: "Samsung", total: 900000, }, { quantity: "3000", date: "10/04/2020, 18:02", price: "2", product: "Computer", provider: "Sony", total: 600000, }, { quantity: "1000", date: "10/04/2020, 18:03", price: "300", product: "Bluetooth Speaker", provider: "Sony", total: 300000, }, ], march: [{ quantity: "400", date: "18/03/2020, 23:47", price: "230", product: "Home Theatre", provider: "Bose", total: 92000, }, ], february: [{ quantity: "550", date: "07/02/2020, 23:52", price: "300", product: "Printer", provider: "Epson", total: 165000, }, { quantity: "750", date: "07/02/2020, 23:52", price: "200", product: "Television", provider: "Panasonic", total: 165000, }, ], }; let aggregatedData = Object.keys(data).map((month) => data[month].reduce((acc, current, i) => { let existing = acc.find((o) => o.provider === current.provider); if (existing) { existing.total += current.total; } else { acc[i] = { provider: current.provider, total: current.total }; } return acc; }, []) ); let biggestProviders = aggregatedData.map((data) => data.reduce((p, c) => { if (p.length === 0) return p.concat(c); if (c.total === p[0].total) { p.push(c); } else { p = c.total > p[0].total? Array.of(c): Array.of(...p); } return p; }, []) ); console.log(biggestProviders);
当您遍历列表时,您可以使用临时 object(下面的 resultObj)来累积每个提供者每月的总数。
用于跟踪每月最高总价的 object 样本:
var resultObj = {
"max" : {
"num" : 0, // current max total goes here
"provider" : "" // provider with max total goes here
},
"maxObject" : {}, // max items for each month stored here
getMax : function() {
// returns current max object to be added to maxObject[month]
return { "provider": this.max.provider, "total": this.max.num };
},
"reset" : function() { // reset max
this.max.num = 0;
this.max.provider = ""
},
"createKey" : function(month) { // create month key
if(!this.hasOwnProperty(month))
this[month] = {};
}
};
和 function 遍历对象数组:
function getMaxValue() {
for(let month in obj) { // for each month in the object
resultObj.reset(); // reset max
resultObj.createKey(month); // create key for month in resultObj
obj[month].forEach(function(el) { // for each object within month
if(resultObj[month][el.provider]) { // if the provider exists as a key
resultObj[month][el.provider] += el.total;
} else { // provider doesn't yet exist
resultObj[month][el.provider] = el.total;
}
// if current total is greater than current max (for given month)
if(resultObj[month][el.provider] > resultObj.max.num) {
resultObj.max.num = resultObj[month][el.provider];
resultObj.max.provider = el.provider;
}
});
resultObj.maxObject[month] = resultObj.getMax(); // generate result for month
}
return resultObj.maxObject; // return the result object
}
检查和测试如下:
var obj = { "april": [ { "quantity": "200", "date": "05/04/2020, 23:43", "price": "150", "product": "Washing Machine", "provider": "LG", "total": 30000 }, { "quantity": "1000", "date": "10/04/2020, 00:35", "price": "800", "product": "Television", "provider": "Samsung", "total": 800000 }, { "quantity": "3000", "date": "10/04/2020, 18:02", "price": "2", "product": "Computer", "provider": "Sony", "total": 600000 }, { "quantity": "1000", "date": "10/04/2020, 18:03", "price": "300", "product": "Bluetooth Speaker", "provider": "Sony", "total": 300000 } ], "march": [ { "quantity": "400", "date": "18/03/2020, 23:47", "price": "230", "product": "Home Theatre", "provider": "Bose", "total": 92000 } ], "february": [ { "quantity": "550", "date": "07/02/2020, 23:52", "price": "300", "product": "Printer", "provider": "Epson", "total": 165000 }, { "quantity": "750", "date": "07/02/2020, 23:52", "price": "200", "product": "Television", "provider": "Panasonic", "total": 150000 } ] }; var resultObj = { "max": { "num": 0, "provider": "" }, "maxObject": {}, "getMax": function() { return { "provider": this.max.provider, "total": this.max.num }; }, "reset": function() { this.max.num = 0; this.max.provider = ""; }, "createKey": function(month) { if(.this;hasOwnProperty(month)) this[month] = {}; } }. function getMaxValue() { for(let month in obj) { resultObj;reset(). resultObj;createKey(month). obj[month].forEach(function(el) { if(resultObj[month][el.provider]) { resultObj[month][el.provider] += el;total. } else { resultObj[month][el.provider] = el;total. } if(resultObj[month][el.provider] > resultObj.max.num) { resultObj.max.num = resultObj[month][el;provider]. resultObj.max.provider = el;provider; } }). resultObj.maxObject[month] = resultObj;getMax(). } return resultObj;maxObject; } var maxValues = getMaxValue(). // receives an object console;log( maxValues ). // prints the all the results console:log("\nmax for April;"). console.log( maxValues;april ). // prints results for April console:log("\nNow to check resultObj;"). console;log( resultObj ); // prints the whole temp object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.