如何按指定Key分组对象数组并合并多键求和结果?
按指定Key分组并对多数值字段求和合并对象
现有一组对象数组,需要按指定Key(如name)进行分组,并将每组内对象的多个数值字段(如value1、value2、value3)求和后合并为单个对象。
示例输入:
[ { name: "test1", value1: 100, value2: 100, value3: 100 }, { name: "test1", value1: 100, value2: 100, value3: 100 }, { name: "test2", value1: 200, value2: 100, value3: 100 }, { name: "test2", value1: 200, value2: 100, value3: 100 }, { name: "test3", value1: 100, value2: 100, value3: 100 } ]
期望输出:
[ { name: "test1", value1: 200, value2: 200, value3: 200 }, { name: "test2", value1: 400, value2: 200, value3: 200 }, { name: "test3", value1: 100, value2: 100, value3: 100 } ]
目前已实现单个数值字段的求和方法,但不知道如何扩展到多字段并合并为完整对象:
const total_sum_data = (arr, key, value) => { const map = new Map(); for (const obj of arr) { const currSum = map.get(obj[key]) || 0; map.set(obj[key], currSum + obj[value]); } const res = Array.from(map, ([k, v]) => ({ [key]: k, [value]: v })); return res; };
解决方法
你可以扩展现有逻辑,让Map存储的不再是单个数值,而是包含分组Key和所有数值字段的累加对象。具体步骤如下:
- 初始化一个
Map,用于存储分组Key对应的累加对象; - 遍历输入数组中的每个对象:
- 取出当前对象的分组Key值;
- 检查Map中是否已有该分组的对象,没有则创建一个初始对象(包含分组Key,且所有数值字段初始化为0);
- 对每个需要求和的数值字段,将当前对象的字段值累加到分组对象对应的字段中;
- 最后将Map中的值转换为数组,得到最终结果。
代码实现
const groupAndSum = (arr, groupKey, sumFields) => { const map = new Map(); for (const obj of arr) { const keyValue = obj[groupKey]; // 获取或初始化分组对象 let groupObj = map.get(keyValue); if (!groupObj) { // 初始化:设置分组Key,同时将所有求和字段设为0 groupObj = { [groupKey]: keyValue }; sumFields.forEach(field => { groupObj[field] = 0; }); map.set(keyValue, groupObj); } // 累加每个数值字段 sumFields.forEach(field => { groupObj[field] += obj[field] || 0; // 处理字段可能不存在的情况 }); } // 将Map的值转为数组返回 return Array.from(map.values()); }; // 使用示例 const inputData = [ { name: "test1", value1: 100, value2: 100, value3: 100 }, { name: "test1", value1: 100, value2: 100, value3: 100 }, { name: "test2", value1: 200, value2: 100, value3: 100 }, { name: "test2", value1: 200, value2: 100, value3: 100 }, { name: "test3", value1: 100, value2: 100, value3: 100 } ]; const result = groupAndSum(inputData, 'name', ['value1', 'value2', 'value3']); console.log(result);
代码说明
- 函数
groupAndSum接收三个参数:输入数组arr、分组键名groupKey、需要求和的字段数组sumFields; - 遍历过程中,每个分组对象会被持续累加对应数值字段的值;
- 加入了
obj[field] || 0的判断,避免对象缺少某个数值字段时出现NaN的情况; - 最终通过
Array.from(map.values())将Map中的分组对象转换为数组,得到符合要求的输出。
内容的提问来源于stack exchange,提问作者fev3r
相关产品推荐
相关产品推荐

