英文:
How can I get the sum of a field having the same Project and Employee name?
问题
我有一个对象数组,我想按项目名称和员工名称对数据进行分组,并在项目和员工已存在的情况下添加小时数。
这是我希望在求和后数据的方式:
projects = [
{ project: "Mars Rover", employee: "Mario", hours: 8 },
{ project: "Mars Rover", employee: "Lucia", hours: 3 },
{ project: "Manhattan", employee: "Giovanni", hours: 7 },
{ project: "Manhattan", employee: "Mario", hours: 2 }
]
实际上,我希望按项目名称和员工名称对数据进行分组,并在项目和员工已存在的情况下添加小时数。以下是我编写的代码:
let newRows = [];
projects.forEach((element) => {
if (newRows.length === 0) {
newRows.push(element);
} else {
const index = newRows.findIndex(
(project) =>
project.project.id === element.project.id &&
project.employee.id === element.employee.id
);
if (index > -1) {
newRows[index].hours += element.hours;
} else {
newRows.push(element);
}
}
});
它有效,但我遇到一个错误。基本上,每当我在该文件中编写代码时,屏幕上的总小时数会自行拉伸,然后我重新加载页面,一切都恢复正常。
这是一个示例:
英文:
I have an Array of objects, I want to group the data by Project Name and Employee Name and, in the case of an existing project and employee, add the hours.
projects = [
{
"project": { "id": 1, "name": "Mars Rover" },
"employee": { "id": 1, "name": "Mario" },
"date": "2021-08-26T22:00:00.000Z",
"hours": 5
},
{
"project": { "id": 2, "name": "Manhattan" },
"employee": { "id": 2, "name": "Giovanni" },
"date": "2021-08-30T22:00:00.000Z",
"hours": 3
},
{
"project": { "id": 1, "name": "Mars Rover" },
"employee": { "id": 1, "name": "Mario" },
"date": "2021-08-31T22:00:00.000Z",
"hours": 3
},
{
"project": { "id": 1, "name": "Mars Rover" },
"employee": { "id": 3, "name": "Lucia" },
"date": "2021-08-31T22:00:00.000Z",
"hours": 3
},
{
"project": { "id": 2, "name": "Manhattan" },
"employee": { "id": 1, "name": "Mario" },
"date": "2021-08-26T22:00:00.000Z",
"hours": 2
},
{
"project": { "id": 2, "name": "Manhattan" },
"employee": { "id": 2, "name": "Giovanni" },
"date": "2021-08-31T22:00:00.000Z",
"hours": 4
}
]
}
This is how I want the data to be after carrying out the sum
projects = [
{project: "Mars Rover", employee: "Mario" hours: 8},
{project: "Mars Rover", employee: "Lucia" hours: 3},
{project: "Manhattan", employee: "Giovanni" hours: 7},
{project: "Manhattan", employee: "Mario" hours: 2}
]
In practice I want to group the data by Project Name and Employee Name and, in the case of an existing project and employee, add the hours.
This is the code I wrote:
let newRows = [];
projects.forEach((element) => {
if (newRows.length === 0) {
newRows.push(element);
} else {
const index = newRows.findIndex(
(project) =>
project.project.id === element.project.id &&
project.employee.id === element.employee.id
);
if (index > -1) {
newRows[index].hours += element.hours;
} else {
newRows.push(element);
}
}
});
It works, but I get a bug. Basically, every time I write code in that file, the total hours on the screen stretch by themselves, then I reload the page and everything goes back to the way it was.
This is an example
答案1
得分: 0
以下是代码的中文翻译:
首先,您可以执行以下操作:
let hours = {};
projects.map((p) => {
if (hours[p.project.name]) {
if (hours[p.project.name][p.employee.name])
hours[p.project.name][p.employee.name] += p.hours;
else hours[p.project.name][p.employee.name] = p.hours;
} else {
hours[p.project.name] = { [p.employee.name]: p.hours };
}
});
一旦您按员工和项目总共的小时数,您可以根据需要进行格式化,例如,您要求的格式如下:
let projectsHours = [];
Object.keys(hours).map((projectName) => {
Object.keys(hours[projectName]).map((employeeName) => {
projectsHours.push({
project: projectName,
employee: employeeName,
hours: hours[projectName][employeeName]
});
});
});
要运行完整的代码,可以使用以下代码:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let projects = [
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 1, name: "Mario" },
date: "2021-08-26T22:00:00.000Z",
hours: 5
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 2, name: "Giovanni" },
date: "2021-08-30T22:00:00.000Z",
hours: 3
},
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 1, name: "Mario" },
date: "2021-08-31T22:00:00.000Z",
hours: 3
},
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 3, name: "Lucia" },
date: "2021-08-31T22:00:00.000Z",
hours: 3
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 1, name: "Mario" },
date: "2021-08-26T22:00:00.000Z",
hours: 2
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 2, name: "Giovanni" },
date: "2021-08-31T22:00:00.000Z",
hours: 4
}
];
let hours = {};
projects.map((p) => {
if (hours[p.project.name]) {
if (hours[p.project.name][p.employee.name])
hours[p.project.name][p.employee.name] += p.hours;
else hours[p.project.name][p.employee.name] = p.hours;
} else {
hours[p.project.name] = { [p.employee.name]: p.hours };
}
});
let projectsHours = [];
Object.keys(hours).map((projectName) => {
Object.keys(hours[projectName]).map((employeeName) => {
projectsHours.push({
project: projectName,
employee: employeeName,
hours: hours[projectName][employeeName]
});
});
});
console.log(projectsHours);
<!-- end snippet -->
英文:
First you can do the following:
let hours = {};
projects.map((p) => {
if (hours[p.project.name]) {
if (hours[p.project.name][p.employee.name])
hours[p.project.name][p.employee.name] += p.hours;
else hours[p.project.name][p.employee.name] = p.hours;
} else {
hours[p.project.name] = { [p.employee.name]: p.hours };
}
});
In the case of your projects, hours
will look like this:
Once you have the total hours by employee by project, you can for sure format it as you want, for instance you requested it like this:
let projectsHours = [];
Object.keys(hours).map((projectName) => {
Object.keys(hours[projectName]).map((employeeName) => {
projectsHours.push({
project: projectName,
employee: employeeName,
hours: hours[projectName][employeeName]
});
});
});
Complete code to run here:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let projects = [
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 1, name: "Mario" },
date: "2021-08-26T22:00:00.000Z",
hours: 5
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 2, name: "Giovanni" },
date: "2021-08-30T22:00:00.000Z",
hours: 3
},
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 1, name: "Mario" },
date: "2021-08-31T22:00:00.000Z",
hours: 3
},
{
project: { id: 1, name: "Mars Rover" },
employee: { id: 3, name: "Lucia" },
date: "2021-08-31T22:00:00.000Z",
hours: 3
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 1, name: "Mario" },
date: "2021-08-26T22:00:00.000Z",
hours: 2
},
{
project: { id: 2, name: "Manhattan" },
employee: { id: 2, name: "Giovanni" },
date: "2021-08-31T22:00:00.000Z",
hours: 4
}
];
let hours = {};
projects.map((p) => {
if (hours[p.project.name]) {
if (hours[p.project.name][p.employee.name])
hours[p.project.name][p.employee.name] += p.hours;
else hours[p.project.name][p.employee.name] = p.hours;
} else {
hours[p.project.name] = { [p.employee.name]: p.hours };
}
});
let projectsHours = [];
Object.keys(hours).map((projectName) => {
Object.keys(hours[projectName]).map((employeeName) => {
projectsHours.push({
project: projectName,
employee: employeeName,
hours: hours[projectName][employeeName]
});
});
});
console.log(projectsHours);
<!-- end snippet -->
答案2
得分: 0
你可以使用map
和reduce
来完成这个任务。
const result = projects.map(el => {
return { project: el.project.name, employee: el.employee.name, hours: el.hours };
}).reduce((acc, elem) => {
const accIndex = acc.findIndex(ai => ai.project === elem.project && ai.employee === elem.employee);
if (accIndex < 0) {
acc.push(elem);
} else {
acc[accIndex].hours += elem.hours;
}
return acc;
}, []);
console.log(result);
英文:
You can do this using map and reduce
const result = projects.map(el => {
return { project: el.project.name, employee: el.employee.name, hours: el.hours};
}).reduce((acc, elem) => {
const accIndex = acc.findIndex(ai => ai.project === elem.project && ai.employee === elem.employee);
if (accIndex < 0) {
acc.push(elem);
} else {
acc[accIndex].hours += elem.hours;
}
return acc;
}, []);
console.log(result);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论