I have an array of objects called employees. I need a solution that will return me a list of groups and respective employees present in the group along with the group properties.
The example is below, I have used an object but the result can also be an array that has a property called groupName within an object. [{groupName:"developer", employees:[],...}..]
As long as the response returns a list of groups with their corresponding employees.
Below is the solution I did but I need a solution with a better time complexity that is O(n).
const employees = [
{ "name": "John Doe",
"id": "1",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "engineerId", "name": "engineer", "color": "#fff" }
],
"groupId":["developerId", "engineerId"]
},
{ "name": "Jane Doe",
"id": "2",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "testerId", "name": "tester", "color": "#fff" }
],
"groupId":["developerId", "testerId"]
}
]
//Solution O(m*n)
let groups = {};
employees.forEach((item) => {
item.groups.forEach((group) => {
if (!groups[group.name]) {
groups[group.name] = {
employees: [item.id],
...group,
};
} else {
groups[group.name].employees = [...groups[group.name].employees, item.id];
}
});
});
//result
{
"developer":{
"id":"developerId",
"employee":[
"1",
"2"
],
"color":"#fff"
},
"engineer":{
"id":"employeeId",
"employee":[
"1",
],
"color":"#fff"
},
"tester":{
"id":"testerId",
"employee":[
"2",
],
"color":"#fff"
}
}
CodePudding user response:
Using Array#reduce
and Array#forEach
:
const employees = [
{
"name": "John Doe",
"id": "1",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "engineerId", "name": "engineer", "color": "#fff" }
],
"groupId": ["developerId", "engineerId"]
},
{
"name": "Jane Doe",
"id": "2",
"groups": [
{ "id": "developerId", "name": "developer", "color": "#fff" },
{ "id": "testerId", "name": "tester", "color": "#fff" }
],
"groupId": ["developerId", "testerId"]
}
];
const groups = employees.reduce((acc, { id: employeeId, groups = [] }) => {
groups.forEach(({ id, name, color }) => {
acc[name] = {
id, color, employee: [...(acc[name]?.employee ?? []), employeeId]
};
});
return acc;
}, {});
console.log(groups);
CodePudding user response:
If you like to add some speed, you could use the old fashioned for
statement for iterating, especially of having only a single result object.
This approach does not create an object again and again and uses the already existing objects.
const
employees = [{ name: "John Doe", id: "1", groups: [{ id: "developerId", name: "developer", color: "#fff" }, { id: "engineerId", name: "engineer", color: "#fff" }], groupId: ["developerId", "engineerId"] }, { name: "Jane Doe", id: "2", groups: [{ id: "developerId", name: "developer", color: "#fff" }, { id: "testerId", name: "tester", color: "#fff" }], groupId: ["developerId", "testerId"] }],
result = {};
for (const { id: employeeId, groups } of employees) {
for (const { id, name, color } of groups) {
result[name] ??= { id, color, employee: [] };
result[name].employee.push(employeeId);
}
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }