如何编写以下数组格式代码的简洁代码?

时间:2018-09-28 09:00:10

标签: javascript

关于对象数组句柄-javascript:

我有一个项目数组,如:

// all projects

var projects = [{
  name: '', 
  company: 'c1',
  skills: ['s1', 's4']
}, {
  name: 'p2', 
  company: 'c2', 
  skills: ['s2']
}, {
  name: 'p3',
  company: 'c3',
  skills: ['s3']
}, {
  name: 'p4',
  company: 'c1',
  skills: ['s1', 's5']
}, {
  name: 'p5',
  company: 'c2',
  skills: ['s3']
}]

如果项目在公司中使用过,我想收集每个公司的技能(如果p1项目使用s1技能,则收集它。)

// results

var companySkills = [{
  company: 'c1',
  skills: ['s1', 's4', 's5']
}, {
  company: 'c2',
  skills: ['s2', 's3']
}, {
  company: 'c3',
  skills: ['s3']
}]

我现在写的是什么

    // what I writing now, I want to improve the code.
    var companySkills = []
    projects.forEach(project => {
      let each = {}
      const alreadyCompany = companySkills.find(companySkill => companySkill.company === project.company)
      if (!alreadyCompany) {
        each.company = project.company
        each.skills = []
      }
      project.skills.forEach(skill => {
        if (alreadyCompany) {
          alreadyCompany.skills = [skill, ...alreadyCompany.skills]
        } else {
          each.skills = [skill, ...each.skills]
        }
      })
      if (!alreadyCompany) {
        companySkills = [each, ...companySkills]
      }
    })

    // final results

    companySkills = companySkills.map(companySkill => ({
      company: companySkill.company,
      skills: [...new Set(companySkill.skills)]
    }))

有没有更好的方法编写更简洁的代码?

3 个答案:

答案 0 :(得分:1)

我建议reduce放入由company索引的对象中,然后可以将其推入累加器中相应对象中的skills数组中(必要时首先创建它) ):

const projects=[{name:'',company:'c1',skills:['s1','s4']},{name:'p2',company:'c2',skills:['s2']},{name:'p3',company:'c3',skills:['s3']},{name:'p4',company:'c1',skills:['s5']},{name:'p5',company:'c2',skills:['s3']}]

const companySkillsObj = projects.reduce((a, { company, skills }) => {
  if (!a[company]) a[company] = { company, skills: [] };
  a[company].skills.push(...skills);
  return a;
}, {});
const companySkills = Object.values(companySkillsObj);
console.log(companySkills);

如果您想避免技能重复,请改用Set

var projects=[{name:'',company:'c1',skills:['s1','s4']},{name:'p2',company:'c2',skills:['s2']},{name:'p3',company:'c3',skills:['s3']},{name:'p4',company:'c1',skills:['s1','s5']},{name:'p5',company:'c2',skills:['s3']}];

const companySkillsObj = projects.reduce((a, { company, skills }) => {
  if (!a[company]) a[company] = new Set();
  skills.forEach(a[company].add, a[company]);
  return a;
}, {});
const companySkills = Object.entries(companySkillsObj)
  .map(([company, set]) => ({ company, skills: [...set] }));
console.log(companySkills);

答案 1 :(得分:0)

您可以在ES6 reduce中使用Map方法,然后获取值。

var projects = [{"name":"","company":"c1","skills":["s1","s4"]},{"name":"p2","company":"c2","skills":["s2"]},{"name":"p3","company":"c3","skills":["s3"]},{"name":"p4","company":"c1","skills":["s5"]},{"name":"p5","company":"c2","skills":["s3"]}]

var result = projects.reduce((r, {company, skills}) => {
  if(!r.get(company)) r.set(company, {company, skills});
  else r.get(company).skills.push(...skills);
  return r;
}, new Map()).values()

console.log(Array.from(result))

要使技能独特而不重复元素,可以先将其设置为Set,然后在最后一次迭代时将其转换为数组。

var projects = [{"name":"","company":"c1","skills":["s1","s4"]},{"name":"p2","company":"c2","skills":["s2"]},{"name":"p3","company":"c3","skills":["s3"]},{"name":"p4","company":"c1","skills":["s1", "s1", "s5", "s5", "s1"]},{"name":"p5","company":"c2","skills":["s3"]}]

var result = projects.reduce((r, {company, skills}, i, arr) => {
  if(!r.get(company)) r.set(company, {company, skills: new Set(skills)});
  else skills.forEach(skill => r.get(company).skills.add(skill))
  if(!arr[i + 1]) r.forEach(p => p.skills = [...p.skills])
  return r;
}, new Map()).values()

console.log(Array.from(result))

答案 2 :(得分:0)

除了其他答案外,还有一种没有Map和Set的方法。

const projects = [{
    name: '',
    company: 'c1',
    skills: ['s1', 's4']
}, {
    name: 'p2',
    company: 'c2',
    skills: ['s2']
}, {
    name: 'p3',
    company: 'c3',
    skills: ['s3']
}, {
    name: 'p4',
    company: 'c1',
    skills: ['s1', 's5']
}, {
    name: 'p5',
    company: 'c2',
    skills: ['s3']
}];

const groupProjects = (array) =>

    // Deconstruct and keep the properties we want
    
    array.reduce((acc, { company, skills }) => {
        
        // find if we already have added this company
        
        const index = acc.findIndex((a) => a.company === company);

        if (index === -1) return acc.concat(({ company, skills }));

        skills.forEach((skill) => {
            
            // add unique skills
            
            if (!acc[index].skills.includes(skill)) acc[index].skills.push(skill);
        });

        return acc;
    }, []);

console.log(groupProjects(projects));