
本文介绍如何高效地按二维数组的第二列(如 'tcn0018')分组,并对第三列数值求和,最终生成以该列为键、总和为值的对象映射。
本文介绍如何高效地按二维数组的第二列(如 'tcn0018')分组,并对第三列数值求和,最终生成以该列为键、总和为值的对象映射。
在处理表格型数据(如导出的 CSV 或数据库查询结果)时,常需按某列去重并聚合其他列——例如按产品编号('TCN0018')归类,累加对应数量。原始代码的问题在于:它仅在首次遇到新 ID 时初始化 amount,但后续同 ID 行未累加,而是直接覆盖 obj_product[id] = amount,导致结果丢失增量(TCN0018 本应是 200 + 300 = 500,却只保留了首项 200)。
推荐使用现代、简洁且健壮的方案:
const values = [
[6285646346643, 'TCN0018', 200, 2000, 5000, 4000],
[6285646346644, 'TCN0018', 300, 2000, 5000, 3000],
[6285646346645, 'TCN0019', 100, 1000, 5000, 4000]
];
const result = Object.create(null);
for (const row of values) {
const id = row[1]; // 第二列:分组键(如 'TCN0018')
const amount = row[2]; // 第三列:待累加数值
result[id] ??= 0; // 若 result[id] 为 undefined,则初始化为 0(空值合并操作符)
result[id] += amount;
}
console.log(result);
// 输出:{ TCN0018: 500, TCN0019: 100 }✅ 关键改进点说明:
- 使用 Object.create(null) 创建无原型的对象,避免 toString 等继承属性干扰,更安全;
- ??=(空值合并赋值)确保每个新键首次访问时被正确初始化为 0,无需预存 ID 列表或额外判断;
- for...of 替代传统 for 循环,语义清晰、可读性强;
- 每行独立处理,逻辑线性:获取键 → 初始化(如需)→ 累加,杜绝覆盖错误。
? 进阶提示(可选):
若需兼容旧环境(不支持 ??=),可替换为 result[id] = (result[id] || 0) + amount;;
若需支持更多聚合方式(如平均值、最大值),可封装为通用 groupByReduce 工具函数;
对于超大数据集,此方案时间复杂度为 O(n),已是最优。
该方法兼顾性能、可维护性与语义表达力,是处理此类分组求和任务的标准实践。
立即学习“Java免费学习笔记(深入)”;


















