在JavaScript中将对象数组转换为嵌套对象数组的方法及思路
数组按Manager分组重塑解决方案
首先,先明确你的输入数据和预期输出:
输入数据
let performanceReview = [ { "name": "Sean", "Manager": "Joe", "Performance": 5}, { "name": "John", "Manager": "Joe", "Performance": 9}, { "name": "Paul", "Manager": "Joe", "Performance": 0}, { "name": "Derek", "Manager": "Greg", "Performance": 10}, { "name": "Lisa", "Manager": "Greg", "Performance": 10}, { "name": "Julia", "Manager": "Donna", "Performance": 7} ];
预期输出
var Series = [ {Manager: "Joe", data: [["Sean", 5], ["John", 9], ["Paul", 0]]}, {Manager: "Greg", data: [["Derek", 10],["Lisa", 10]]}, {Manager: "Donna", data: [["Julia", 7]]} ];
实现代码
用Array.prototype.reduce()可以高效完成这个分组重塑,代码如下:
let performanceReview = [ { "name": "Sean", "Manager": "Joe", "Performance": 5}, { "name": "John", "Manager": "Joe", "Performance": 9}, { "name": "Paul", "Manager": "Joe", "Performance": 0}, { "name": "Derek", "Manager": "Greg", "Performance": 10}, { "name": "Lisa", "Manager": "Greg", "Performance": 10}, { "name": "Julia", "Manager": "Donna", "Performance": 7} ]; const Series = performanceReview.reduce((acc, current) => { // 查找当前Manager是否已在结果数组中存在条目 const existingEntry = acc.find(item => item.Manager === current.Manager); if (existingEntry) { // 已存在则追加当前员工的数据到对应data数组 existingEntry.data.push([current.name, current.Performance]); } else { // 不存在则新建一个Manager条目并加入结果数组 acc.push({ Manager: current.Manager, data: [[current.name, current.Performance]] }); } return acc; }, []); console.log(Series); // 输出就是你要的预期结果
解决思路讲解
这个问题本质是按字段分组并聚合子数据,我拆解下思路:
选对核心方法: 用
reduce是最适合的,它能在一次遍历中完成分组逻辑,不需要额外的外部变量来存储中间结果,代码更紧凑高效。reduce的第二个参数[]是我们的初始累加器,也就是最终要返回的数组。分组逻辑拆解:
- 遍历每一个员工对象时,先检查累加器(正在构建的结果数组)里有没有当前员工的Manager对应的条目。
- 如果有,就把当前员工的
name和Performance组成数组,追加到该条目的data数组里。 - 如果没有,就新建一个包含该Manager和初始
data(当前员工的[name,绩效]数组)的对象,然后把这个对象加入累加器。
大数据量优化思路: 如果你的数据量很大,
find方法每次遍历累加器会有点慢,这时候可以先用一个临时对象来做映射(key是Manager名字,value是对应的条目),最后再把对象的值转成数组,这样时间复杂度从O(n²)降到O(n),比如:
const tempMap = {}; performanceReview.forEach(item => { if (!tempMap[item.Manager]) { tempMap[item.Manager] = { Manager: item.Manager, data: [] }; } tempMap[item.Manager].data.push([item.name, item.Performance]); }); const Series = Object.values(tempMap);
这个版本对于大数据量的场景更友好,执行速度更快。
内容的提问来源于stack exchange,提问作者Shayanian
相关产品推荐
相关产品推荐

