从 Javascript 中的重复项分组的另一个数组创建一个对象数组

Create an array of objects from another array grouping duplicates in Javascript

我需要根据对象的其中一个属性将一组对象(来自数据库)重新组织成不同的组。为了更清楚,让我们举个例子:

ORM(Sequelize)returns以下数组对象:

[
  {
    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,
  },
]

我需要对按 employeeId 对条目进行分组的对象重新分类。像这样:

[
  {
    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}
           ]
   }
]

起初看起来并不难,但我遇到了障碍,我已经尝试使用 reduce、forEarch 和 map,但我只需要制作一个 employeeIds 数组,无法真正包含这些技能数组的每个对象中的数组。

如有任何帮助,我们将不胜感激。

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

此方法使用 类 构建员工对象,将来可以轻松扩展。

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