2

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.

2 Answers 2

3

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))

Sign up to request clarification or add additional context in comments.

Comments

2

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.