如何按portfolio与sendType条件合并对象为结构化数组?
JavaScript 对象数组按指定字段分组并汇总金额
需求说明:
将给定的JavaScript对象数组myData,按portfolio与sendType字段进行分组合并;同一分组下,把regiserDate作为属性名,对应amount的汇总值作为属性值,最终生成一个扁平化的对象数组(非父子嵌套结构)。
原始数据
var myData = [{ "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Capitalization", "amount": 1000, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Capitalization", "amount": 3000, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Capitalization", "amount": 6000, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Capitalization", "amount": 7000, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-02-27", "sendType": "Accure", "amount": 999, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-02-27", "sendType": "Accure", "amount": 9999, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-02-27", "sendType": "Capitalization", "amount": 3, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-01-27", "sendType": "Accure", "amount": 4, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-04-27", "sendType": "Capitalization", "amount": 6, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-05-27", "sendType": "Capitalization", "amount": 7, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-06-27", "sendType": "Capitalization", "amount": 8, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-02-27", "sendType": "Capitalization", "amount": 10, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-07-27", "sendType": "payable", "amount": 12, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-01-27", "sendType": "Accure", "amount": 13, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-09-27", "sendType": "Accure", "amount": 14, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-08-27", "sendType": "Accure", "amount": 16, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-09-27", "sendType": "Accure", "amount": 17, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-11-27", "sendType": "Accure", "amount": 18, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-11-27", "sendType": "Accure", "amount": 19, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-01-27", "sendType": "payable", "amount": 20, "__typename": "taxCalculation" }, { "portfolio": "Retail", "regiserDate": "2021-01-27", "sendType": "Accure", "amount": 21, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Accure", "amount": 22, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-12-27", "sendType": "Accure", "amount": 28, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-11-27", "sendType": "payable", "amount": 30, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "AccureAccureAccure", "amount": 33, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "AccureAccure", "amount": 35, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-01-27", "sendType": "Accure", "amount": 45, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "regiserDate": "2021-04-27", "sendType": "Capitalization", "amount": 49, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-07-27", "sendType": "payable", "amount": 87, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-07-27", "sendType": "Capitalization", "amount": 81, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-08-27", "sendType": "Accure", "amount": 65, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-01-27", "sendType": "payable", "amount": 470, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "regiserDate": "2021-05-27", "sendType": "payable", "amount": 540, "__typename": "taxCalculation" } ];
预期结果
var result = [{ "portfolio": "Consumer", "sendType": "Capitalization", "2021-01-27": 17000, "2021-04-27": 49, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "sendType": "Accure", "2021-01-27": 67, "2021-08-27": 16, "2021-09-27": 17, "2021-11-27": 18, "2021-12-27": 28, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "sendType": "payable", "2021-11-27": 30, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "sendType": "AccureAccureAccure", "2021-01-27": 33, "__typename": "taxCalculation" }, { "portfolio": "Consumer", "sendType": "AccureAccure", "2021-01-27": 35, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "sendType": "Accure", "2021-02-27": 10998, "2021-01-27": 4, "2021-08-27": 65, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "sendType": "Capitalization", "2021-02-27": 3, "2021-04-27": 6, "2021-07-27": 81, "__typename": "taxCalculation" }, { "portfolio": "Commercial", "sendType": "payable", "2021-07-27": 87, "2021-01-27": 470, "2021-05-27": 540, "__typename": "taxCalculation" }, { "portfolio": "Retail", "sendType": "Capitalization", "2021-05-27":7, "2021-06-27":8, "2021-02-27":10, "__typename": "taxCalculation" }, { "portfolio": "Retail", "sendType": "payable", "2021-07-27":12, "2021-01-27":20, "__typename": "taxCalculation" }, { "portfolio": "Retail", "sendType": "Accure", "2021-01-27":34, "2021-09-27":14, "2021-11-27":19, "__typename": "taxCalculation" } ];
注:原预期结果中的金额为示例占位值,上述结果为实际汇总后的数据。
实现方案
可以使用Array.reduce()方法完成分组与汇总,核心逻辑如下:
- 用临时对象做映射表,以
portfolio+sendType的组合字符串作为唯一键,区分不同分组。 - 遍历原始数组元素:
- 若映射表中无当前分组,初始化包含基础字段的对象,并添加当前日期的金额。
- 若映射表中已有当前分组,检查对应日期属性,存在则累加金额,不存在则新增属性并赋值。
- 最后将映射表的所有值转换为数组,得到最终结果。
代码实现
const result = Object.values(myData.reduce((acc, item) => { // 生成唯一分组标识 const key = `${item.portfolio}-${item.sendType}`; if (!acc[key]) { // 初始化分组对象 acc[key] = { portfolio: item.portfolio, sendType: item.sendType, __typename: item.__typename }; } // 汇总对应日期的金额 acc[key][item.regiserDate] = (acc[key][item.regiserDate] || 0) + item.amount; return acc; }, {})); console.log(result);
内容的提问来源于stack exchange,提问作者Jolen Qadar
相关产品推荐
相关产品推荐

