英文:
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论