I have an Array of objects, I want to group the data by Project Name and, in the case of an existing project, sum 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", hours: 11},
{project: "Manhattan", hours: 9}
]
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
);
console.log(index);
if (index > -1) {
newRows[index].hours += element.hours;
} else {
newRows.push(element);
}
}
});
I created a new array and went to populate it. I researched the common id.
This code works but I am getting a bug. In practice, every time I write code in that file, the total hours on the screen increase by themselves, then I reload the page and everything returns as before.
4
Answers
I have another case to handle, and I'd like to take the same approach. I always have the same array of objects:
This is how I want the data to be after carrying out the sum
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:
It works, but I rightfully get the same bug as the first example. Basically, every time I write code in that file, the total hours on the screen increase by themselves, then I reload the page and everything goes back to the way it was.
enter image description here
You can do the following:
In the case of your projects,
hours
will look like this:Once you have the total hours by project, you can for sure format it as you want, for instance you requested it like this:
Complete code to run here:
Whenever the code runs it continues adding to the
newRows
array, instead of recalculating the data from scratch. In addition, to update rows, you need to find them, which makes the code less optimal.Reduce the
projects
to aMap
, and then convert theMap
back to an array usingArray.from()
:You can first create an object which looks like this using a reducer. The key of this object is the ID of the project.
Then you can throw that object into
Object.values
which will convert it into an array for you:It looks nicer without the comments, but broke it down for you.