如何获取具有相同项目和员工名称的字段的总和?

huangapple go评论78阅读模式
英文:

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

enter image description here

答案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 };
  }
});

在您的projects的情况下,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) =&gt; {
  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) =&gt; {
  Object.keys(hours[projectName]).map((employeeName) =&gt; {
    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: &quot;Mars Rover&quot; },
    employee: { id: 1, name: &quot;Mario&quot; },
    date: &quot;2021-08-26T22:00:00.000Z&quot;,
    hours: 5
  },
  {
    project: { id: 2, name: &quot;Manhattan&quot; },
    employee: { id: 2, name: &quot;Giovanni&quot; },
    date: &quot;2021-08-30T22:00:00.000Z&quot;,
    hours: 3
  },
  {
    project: { id: 1, name: &quot;Mars Rover&quot; },
    employee: { id: 1, name: &quot;Mario&quot; },
    date: &quot;2021-08-31T22:00:00.000Z&quot;,
    hours: 3
  },
  {
    project: { id: 1, name: &quot;Mars Rover&quot; },
    employee: { id: 3, name: &quot;Lucia&quot; },
    date: &quot;2021-08-31T22:00:00.000Z&quot;,
    hours: 3
  },
  {
    project: { id: 2, name: &quot;Manhattan&quot; },
    employee: { id: 1, name: &quot;Mario&quot; },
    date: &quot;2021-08-26T22:00:00.000Z&quot;,
    hours: 2
  },
  {
    project: { id: 2, name: &quot;Manhattan&quot; },
    employee: { id: 2, name: &quot;Giovanni&quot; },
    date: &quot;2021-08-31T22:00:00.000Z&quot;,
    hours: 4
  }
];

let hours = {};
projects.map((p) =&gt; {
  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) =&gt; {
  Object.keys(hours[projectName]).map((employeeName) =&gt; {
    projectsHours.push({
      project: projectName,
      employee: employeeName,
      hours: hours[projectName][employeeName]
    });
  });
});

console.log(projectsHours);

<!-- end snippet -->

答案2

得分: 0

你可以使用mapreduce来完成这个任务。

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 =&gt; {
	return { project: el.project.name, employee: el.employee.name, hours: el.hours};
}).reduce((acc, elem) =&gt; {
   const accIndex = acc.findIndex(ai =&gt; ai.project === elem.project &amp;&amp; ai.employee === elem.employee);
   if (accIndex &lt; 0) {
	 acc.push(elem);
   } else {
  	 acc[accIndex].hours += elem.hours;
   }
   return acc;
}, []);
console.log(result);

huangapple
  • 本文由 发表于 2023年3月8日 18:30:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75671870.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定