如何使用Array.reduce()对JSON数据按列求和?
按ID对多组data的value列求和的实现方案
首先先修正你提供的输入JSON的语法错误(每个对象末尾缺少闭合的}),修正后的输入如下:
[ {"name": "a", "data": [{"value":10,"id":1},{"value":20,"id":2}]}, {"name": "b", "data": [{"value":10,"id":1},{"value":20,"id":2}]}, {"name": "c", "data": [{"value":10,"id":1},{"value":20,"id":2}]}, {"name": "d", "data": [{"value":10,"id":1},{"value":20,"id":2}]}, {"name": "e", "data": [{"value":10,"id":1},{"value":20,"id":2}]} ]
下面提供几种基于Array.reduce()的实现方式,还有其他可选方案:
方案一:直接用数组作为累加器(直观易懂)
这种方式用数组作为reduce的初始值,遍历每个对象的data条目,检查累加数组中是否已有对应id的记录,有则累加value,没有则新增条目:
const input = [/* 上面修正后的数组 */]; // 用reduce累加每个id的value const summedData = input.reduce((acc, currentGroup) => { currentGroup.data.forEach(item => { // 查找累加数组中对应id的条目 const existingEntry = acc.find(entry => entry.id === item.id); if (existingEntry) { existingEntry.value += item.value; } else { // 复制条目到累加数组(避免修改原数据) acc.push({ ...item }); } }); return acc; }, []); // 包装成目标结构 const finalResult = { name: "something", data: summedData }; console.log(finalResult);
方案二:用对象作为累加器(性能更优)
如果你的数据量较大,用对象作为累加器会更高效(对象键查找是O(1),而数组find是O(n)):
const input = [/* 修正后的数组 */]; // 先构建id到累计value的映射 const valueMap = input.reduce((map, currentGroup) => { currentGroup.data.forEach(item => { // 存在则累加,不存在则初始化为当前value map[item.id] = (map[item.id] || 0) + item.value; }); return map; }, {}); // 把映射转换成要求的数组格式 const summedData = Object.entries(valueMap).map(([id, value]) => ({ id: Number(id), // 把字符串id转回数字类型 value })); const finalResult = { name: "something", data: summedData }; console.log(finalResult);
其他可选方案:先扁平化再处理
如果你觉得分步处理更清晰,可以先把所有data数组扁平化成一个大数组,再用reduce累加:
const input = [/* 修正后的数组 */]; // 扁平化所有data条目到一个数组 const allItems = input.flatMap(group => group.data); // 累加每个id的value const valueMap = allItems.reduce((map, item) => { map[item.id] = (map[item.id] || 0) + item.value; return map; }, {}); // 转换为目标格式 const summedData = Object.entries(valueMap).map(([id, value]) => ({id: Number(id), value})); const finalResult = { name: "something", data: summedData };
以上几种方案都能实现你要的效果,其中方案二在数据量大时性能更好,方案一和扁平化方案更直观易读,可以根据你的场景选择。
内容的提问来源于stack exchange,提问作者Keshav1007
相关产品推荐
相关产品推荐

