Reputation: 374
I need to re-organize an array of objects (from a database) into different groups according to one of the attributes of objects. To make it clearer, let's take the following example:
The ORM (Sequelize) returns the following array object:
[
{
id: 182,
employeeId: 'a',
skillId: 207,
score: 3,
},
{
id: 512,
employeeId: 'a',
skillId: 212,
score: 4,
},
{
id: 908,
employeeId: 'b',
skillId: 134,
score: 2,
},
{
id: 876,
employeeId: 'c',
skillId: 212,
score: 3,
},
]
I need to re-categorize the object grouping the entries by employeeId. Like this:
[
{
employeeId: 'a',
skills:
[
{ skillId: 203, score: 3},
{ skillId: 212, score: 4}
]
},
{
employeeId: 'b',
skills:
[
{ skillId: 134, score: 2}
]
},
{
employeeId: 'c',
skills:
[
{ skillId: 212, score: 3}
]
}
]
It didn't look hard at first but I'm hitting a roadblock, I already tried using reduce, forEarch and map but I only got to make an array of employeeIds, can't really get to include the skills array in each object of the array.
Any help would be appreciated.
Upvotes: 2
Views: 828
Reputation: 41
This approach uses classes to build up the employee object and could be easily extended in the future.
const input = [{
id: 182,
employeeId: 'a',
skillId: 207,
score: 3,
},
{
id: 512,
employeeId: 'a',
skillId: 212,
score: 4,
},
{
id: 908,
employeeId: 'b',
skillId: 134,
score: 2,
},
{
id: 876,
employeeId: 'c',
skillId: 212,
score: 3,
},
];
const employeeMap = {};
class Skill {
constructor({
skillId,
score
}) {
this.skillId = skillId;
this.score = score;
}
}
class Employee {
constructor(rawEmployee) {
this.employeeId = rawEmployee.employeeId;
this.skills = [];
}
addSkill(rawEmployee) {
this.skills.push(new Skill(rawEmployee));
}
}
for (let i = 0; i < input.length; i++) {
const rawEmployee = input[i];
let employee = employeeMap[rawEmployee.employeeId];
if (!employee) {
employee = new Employee(rawEmployee);
employeeMap[employee.employeeId] = employee;
}
if (employee) {
employee.addSkill(rawEmployee);
}
}
const employeeArray = [];
for (let key in employeeMap) {
employeeArray.push(employeeMap[key]);
}
console.log(employeeArray);
console.log(JSON.stringify(employeeArray));
Upvotes: 2
Reputation: 46
const result = [
{
id: 182,
employeeId: 'a',
skillId: 207,
score: 3,
},
{
id: 512,
employeeId: 'a',
skillId: 212,
score: 4,
},
{
id: 908,
employeeId: 'b',
skillId: 134,
score: 2,
},
{
id: 876,
employeeId: 'c',
skillId: 212,
score: 3,
},
]
const tempObj = result.reduce((acc, curr) => {
if (curr.employeeId in acc) {
acc[curr.employeeId].push({
skillId: curr.skillId,
score: curr.score
})
} else {
acc[curr.employeeId] = [{
skillId: curr.skillId,
score: curr.score
}]
}
return acc
}, {})
const reorganized = Object.keys(tempObj).map(key => ({
employeeId: key,
skills: tempObj[key]
}))
console.log(JSON.stringify(reorganized, null, 2))
Upvotes: 3