生成具有属性值计数的新数组

时间:2019-01-27 19:25:03

标签: javascript arrays object for-loop

我的状态中有一个数组:

projects: [
{ title: 'todo 1', person: 'Sam', status: 'ongoing'},
{ title: 'project', person: 'Jack', status: 'complete' },
{ title: 'Design video', person: 'Tim', status: 'complete' },
{ title: 'Create a forum', person: 'Jade', status: 'overdue' },
{ title: 'application', person: 'Jade', status: 'ongoing'},],

从这个数组(项目)中,我想用Javascript生成一个新数组并得到以下结果:

totalByPersonAndStatus : [
{person : 'Sam', complete: 0, ongoing: 1, overdue: 0 },
{person : 'Jack', complete: 1, ongoing: 0, overdue: 0 },
{person : 'Tim', complete: 1, ongoing: 0, overdue: 0 },
{person : 'Jade', complete: 0, ongoing: 1, overdue: 1 },]

我尝试过

totalProjectsByPersonAndStatus: state => {
state.projects.forEach(name => {
  state. totalByPersonAndStatus["name"] = name.person;
});

return state. totalByPersonAndStatus;

问题,如果创建console.log(this.totalByPersonAndStatus)我有一个仅包含projects.name [name: "Jade", __ob__: Observer]

数据的对象

你能帮我吗? 谢谢

3 个答案:

答案 0 :(得分:0)

您可以使用reduce

let projects =[{title:'todo1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Designvideo',person:'Tim',status:'complete'},{title:'Createaforum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'},]

let desired = projects.reduce((output,{person,status}) => {
  if( output[person] ){
    output[person][status]++
  } else {
    output[person] = {
      person,
      complete: Number(status==='complete'),
      ongoing: Number(status==='ongoing'),
      overdue: Number(status==='overdue')
    }
  }
  return output;
},{})

console.log(Object.values(desired))

答案 1 :(得分:0)

您可以使用reduce并进行如下破坏:

const projects=[{title:'todo 1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Design video',person:'Tim',status:'complete'},{title:'Create a forum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'}]

const merged = projects.reduce((acc,{person,status})=>{
  acc[person] = acc[person] || { person, ongoing:0, complete:0, overdue:0}
  acc[person][status]++;
  return acc;
},{})

console.log(Object.values(merged))

目标是创建一个对象merged,每个person作为键,然后根据状态递增:

{
  "Sam": {
    "person": "Sam",
    "ongoing": 1,
    "complete": 0,
    "overdue": 0
  },
  "Jack": {

  }
  ...
}

然后使用Object.values获得最终数组。

您可以将它设为单线:

const projects=[{title:'todo 1',person:'Sam',status:'ongoing'},{title:'project',person:'Jack',status:'complete'},{title:'Design video',person:'Tim',status:'complete'},{title:'Create a forum',person:'Jade',status:'overdue'},{title:'application',person:'Jade',status:'ongoing'}],

output = Object.values(projects.reduce((a,{person,status})=>
  ((a[person] = a[person] || {person,ongoing:0,complete:0,overdue:0})[status]++,a),{}))

console.log(output)

答案 2 :(得分:0)

通过遍历项目来创建人员和状态的新集合,一个集合只有唯一的值,因此集合很方便,遍历您的人员集合以创建所有状态都初始化为0的新对象,然后在项目以增加适用的各种状态。这种方法允许添加任何数量的新状态,而无需更改代码-动态。

var people = new Set();
var status = new Set();   

projects.forEach((p)=>{
    people.add(p.person);
    status.add(p.status);
});

var totalByPersonAndStatus = [];

people.forEach((person)=>{
    let peeps = { "person": person };
    status.forEach((stat)=>{
        peeps[stat] = 0;
    });
    projects.forEach((project)=>{
        if (project.person === person) { peeps[project.status]++; }
    });
    totalByPersonAndStatus.push(peeps);
});