首页 > 解决方案 > 使用reduce函数将数组汇总为对象

问题描述

我的任务是汇总一个包含 500 多个其他数组的数组。以下是一些条目的示例var list

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "sandra.m@email.com"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "john.a@email.com"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "john.a@email.com"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "MYA",
    "LANE",
    456,
    "john A",
    "john.a@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "sandra.m@email.com"
  ]
]

我认为这将是 reduce 函数的绝佳候选者,但我找不到正确使用它的方法。

我想创建一个简单的数组{},将数据汇总为以下内容:

var result = [
{
  supervisor: "Sandra M.",   //supervisor name   
  email: sandra.a@email.com, //supervisor email
  employees: 2,              //number of employees supervised by Sandra
  entries: 4                 //total number of items in array with Sandra as the supervisor
},
{
  supervisor: "John A.",     //supervisor name
  email: john.a@email.com,   //supervisor email
  employees: 2,              //number of employees supervised by John
  entries: 3                 //total number of items in array with John as the supervisor
}
]

这是我卡住的地方:

var result= list.reduce(function(all,item){
    all[item[3]] = all[item[3]] || []
    all[item[3]].push({
       supervisor: item[3],
       email: item[4],
       employees: item[2]++,
       entries: item[0]++,
    })
  return all
},{})

标签: javascriptarraysreduce

解决方案


这里的主要困难似乎是将员工与(非员工)条目区分开来。看起来所有非员工条目项目在输入数组中都有 6 个项目(包括月份的值),而员工没有月份。通过检查您正在迭代的内容的长度,可以很容易地识别出这一点。

缩减为主管电子邮件索引的对象,如果事先不存在,则在该点创建一个对象。然后,如果您正在迭代的项目是员工,则增加该employees属性(并且entries无论如何都增加该属性)。

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "sandra.m@email.com"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "john.a@email.com"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "john.a@email.com"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "MYA",
    "LANE",
    456,
    "February",
    "john A",
    "john.a@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "March",
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "March",
    "Sandra M.",
    "sandra.m@email.com"
  ]
]

var resultObj = list.reduce(function(all,item){
    const isEmployee = item.length === 5;
    const [supervisor, email] = item.slice(-2);
    if (!all[email]) {
      all[email] = { supervisor, email, employees: 0, entries: 0 };
    }
    if (isEmployee) {
      all[email].employees++;
    }
    all[email].entries++;
    
  return all
},{});
const result = Object.values(resultObj);
console.log(result);

对于新的数据结构,制作一组已被视为员工的 id。如果您正在迭代的项目包含在该 Set 中,请不要添加到员工计数中:

var list = [
  [
    "MIKE",               //employee first
    "NGUYEN",             //employee last
    123,                  //id
    "Sandra M.",          //supervisor name 
    "sandra.m@email.com"  //supervisor email
  ],
  [
    "MYA",
    "LANE",
    456,
    "John A",
    "john.a@email.com"
  ],
  [
    "RON",
    "MASTER",
    789,
    "John A",
    "john.a@email.com"
  ],
  [
    "MIKE",
    "NGUYEN",
    123,
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "MYA",
    "LANE",
    456,
    "john A",
    "john.a@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "sandra.m@email.com"
  ],
  [
    "ROBERT",
    "RULES",
    100,
    "Sandra M.",
    "sandra.m@email.com"
  ]
]

const seenIds = new Set();
var resultObj = list.reduce(function(all,item){
    const [id, supervisor, email] = item.slice(-3);
    if (!all[email]) {
      all[email] = { supervisor, email, employees: 0, entries: 0 };
    }
    if (!seenIds.has(id)) {
      all[email].employees++;
      seenIds.add(id);
    }
    all[email].entries++;
    
  return all
},{});
const result = Object.values(resultObj);
console.log(result);


推荐阅读