[英]Sum values of array of object grouped by keys and return into a new array of arrays
我需要对按两个属性分组的所有值求和: "date"
和"zona"
。 特别是,我想将"date"
翻译成星期几,并按它分组。 对于"zona"
我想按“zona 1”、“zona 2”、“zona 3”等分组。
预期结果:
[dayOfWeek, zoneId, value];
[
[0, 0, something],
[0, 1, something],
...
[0, 9, something],
[1, 0, something],
...
[6, 9, something]
]
我已经做了类似的事情(这里是jsfiddle):
数据初始化:
const data = [
{
"date": "2017/12/31",
"ALL.new users": 298,
"ALL.returning users": 12528,
"zona 1.new users": 189,
"zona 1.returning users": 3422,
"zona 10.new users": 18,
"zona 10.returning users": 2767,
"zona 2.new users": 11,
"zona 2.returning users": 1216,
"zona 3.new users": 20,
"zona 3.returning users": 3175,
"zona 4.new users": 5,
"zona 4.returning users": 1465,
"zona 5.new users": 3,
"zona 5.returning users": 1102,
"zona 6.new users": 20,
"zona 6.returning users": 2223,
"zona 7.new users": 2,
"zona 7.returning users": 1063,
"zona 8.new users": 25,
"zona 8.returning users": 1093,
"zona 9.new users": 3,
"zona 9.returning users": 1507
}, {...}
];
const zoneMapping = {
"Zone 1": 0,
"Zone 2": 1,
"Zone 3": 2,
"Zone 4": 3,
"Zone 5": 4,
"Zone 6": 5,
"Zone 7": 6,
"Zone 8": 7,
"Zone 9": 8,
"Zone 10": 9
};
const dayMapping = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
功能:
let tempSeriesData = [];
data.forEach(
(item) => {
const date = (new Date(item.date)).getDay();
Object.entries(item).forEach(([key, value]) => {
if (key !== "date" && key !== "ALL.new users" && key !== "ALL.returning users" && !key.includes("new users")) {
let tempYValue = key.slice(0, 7).replace(".", "");
tempYValue = tempYValue.replace("a", "e");
const yValue = tempYValue.charAt(0).toLocaleUpperCase() + tempYValue.slice(1)
const dataValue = Number(value);
const element = [
date,
zoneMapping[yValue],
dataValue
];
const existingElement = tempSeriesData.find(el => el[0] === element[0] && el[1] === element[1]);
if (existingElement) {
existingElement[2] += element[2];
}
else {
tempSeriesData.push(element);
}
}
});
}
);
有了这个函数,我可以获得我想要的东西,但我正在寻找一种新方法来做同样的事情,也许使用 map()、reduce 或其他东西,因为我想改进这些方法的使用。
提前感谢您的回答。
其实还好代码是明确的,它做了它应该做的。 如果我们真的想重构它,为了清晰起见,我会使用对象,然后在数组中进行转换。 另外我会使用 map/reduce 而不是全局 var + forEach 循环。
const parser = (item) => {
const date = (new Date(item.date)).getDay();
myItem = Object.entries(item).flatMap(([key, value]) => {
key = key.split(/[\s.]+/) // split the key on SPACE and DOT at the same time
// Maybe I misunderstand the IF from before but this works right now.
return key[2] === "returning" ? [{ day: date, zone: key[1] - 1, value: Number(value) }] : []
})
return myItem
}
// upsert adds elements to the object if new or update existing
const upSert = (acc, { value, ...r }) => {
key = JSON.stringify(r) // Since it is a nested map, we make our life easier with unique keys.
acc[key] = (acc[key] || { ...r, value: 0 }); // if null initialize
return (acc[key].value += value, acc) // update in place
}
const toValueArray = (data) => {
return Object.values(data).map(d => Object.values(d))
}
//This could be already populated from a previous run
// Probably comming as a prop to a component
seriesData = {}
myTs = data.flatMap(parser)
.reduce(upSert, seriesData)
const finalSeriesData = toValueArray(myTs)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.