javascript - 使用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
},{})
解决方案
这里的主要困难似乎是将员工与(非员工)条目区分开来。看起来所有非员工条目项目在输入数组中都有 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);
推荐阅读
- bash - 如何使用 systemd timer 下载并执行远程 bash 脚本?
- mysql - MySql,UNION 时重复 Select IN (Select()) 的替代方法
- php - 如何根据 PHP 中的两列计算数组值?
- php - 根据单词相似度将一个 varchar 与另一个 varchar 进行比较
- reactjs - Nginx 和多个 React Web 应用程序
- c++ - 中级 C++ 开发人员的棘手面试问题
- r - R studio 找不到现有库
- javascript - 如何滚动垂直导航选项卡
- python - ImportError:无法导入名称“GceClusterResolver”
- ios - MDCTextInputController 错误消息涵盖输入的文本