You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按atributo中的id分组聚合对象数组并求和valor字段?

正确实现按atributo.id分组求和的方案

你的思路方向是对的,但原reduce代码存在几个关键问题:

  • 没有给reduce设置初始值,导致第一次迭代时acc是数组的第一个元素,后续如果执行return a + Number(b.valor),acc会变成数字,再迭代时访问a.atributo.id就会直接报错(数字没有atributo属性)。
  • 逻辑上没有维护多分组的存储,只能尝试处理连续的同组元素,没法同时保存多个不同atributo.id的分组数据。

下面是完整的正确实现:

const myArr = [{id: 21852, atributo: {id: 20}, valor: "876.98"}, {id: 21853, atributo: {id:21}, valor: "760"}, {id: 21858, atributo: {id:20}, valor: "876.98"}, {id: 21859, atributo: {id:21}, valor: "760"}];

// 1. 用reduce创建分组映射,key为atributo.id,value存储分组的属性和累加值
const groupMap = myArr.reduce((acc, currentItem) => {
  const attrId = currentItem.atributo.id;
  // 如果当前分组不存在,初始化结构
  if (!acc[attrId]) {
    acc[attrId] = {
      atributo: {...currentItem.atributo}, // 浅拷贝避免原对象被修改
      valor: 0
    };
  }
  // 将当前item的valor转成数字后累加
  acc[attrId].valor += parseFloat(currentItem.valor);
  return acc;
}, {}); // 必须传入初始空对象,确保acc始终是对象类型

// 2. 将分组映射转成目标数组,并添加自增的id
const finalResult = Object.values(groupMap).map((groupItem, index) => ({
  id: index + 1,
  ...groupItem,
  // 把求和后的数字转成带逗号分隔的格式(匹配你期望的输出)
  valor: groupItem.valor.toFixed(2).replace('.', ',')
}));

console.log(finalResult);
// 输出结果:
// [{id: 1, atributo: {id: 20}, valor: "1753,96"}, {id: 2, atributo: {id:21}, valor: "1520,00"}]

额外说明:

  • 如果你的valor原始数据中存在逗号作为小数分隔符(比如"876,98"),需要先替换成点再转数字:parseFloat(currentItem.valor.replace(',', '.'))。
  • 如果不需要保留小数位,可以把toFixed(2)去掉,直接用groupItem.valor.toString().replace('.', ','),或者根据需求处理数字格式。

内容的提问来源于stack exchange,提问作者gwerle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:37:32