
本文介绍使用 javascript 的 reduce 与 object.values 高效地按多个属性(如 index 和 name)对对象数组分组,并合并对应数组字段(如 price),避免重复、保持结构清晰。
本文介绍使用 javascript 的 reduce 与 object.values 高效地按多个属性(如 index 和 name)对对象数组分组,并合并对应数组字段(如 price),避免重复、保持结构清晰。
在实际开发中,常需将具有相同标识字段的对象归并为一组,并聚合其嵌套数组(如价格列表)。本例要求:依据 index 和 name 两个属性联合分组,并将同组所有对象的 price 数组扁平合并(而非覆盖或嵌套)。
核心思路是:
- 构造唯一分组键(如 "4|car"),由目标属性值拼接而成;
- 利用 reduce 构建以该键为索引的哈希表,每个键对应一个初始化后的分组对象;
- 使用空数组作为 price 初始值,通过扩展运算符 ...price 累积追加;
- 最终通过 Object.values() 提取所有分组结果,得到纯净数组。
以下是完整可运行示例代码:
const data = [
{ index: 4, name: "car", price: [10, 20, 30] },
{ index: 4, name: "car", price: [40, 50, 60] },
{ index: 3, name: "bike", price: [40, 50, 60] },
{ index: 2, name: "scooter", price: [10, 20, 60] },
{ index: 2, name: "scooter", price: [70] }
];
const keys = ['index', 'name']; // 指定用于分组的属性名
const grouped = Object.values(
data.reduce((acc, { price, ...rest }) => {
const key = keys.map(k => rest[k]).join('|');
// 若键不存在,则初始化:展开 rest 并设置 price 为空数组
acc[key] ??= { ...rest, price: [] };
// 合并当前 price 数组的所有元素
acc[key].price.push(...price);
return acc;
}, Object.create(null))
);
console.log(grouped);
// 输出:
// [
// { index: 4, name: "car", price: [10, 20, 30, 40, 50, 60] },
// { index: 3, name: "bike", price: [40, 50, 60] },
// { index: 2, name: "scooter", price: [10, 20, 60, 70] }
// ]
✅ 关键优势:
- 使用 Object.create(null) 避免原型链污染,提升键安全性;
- ??=(空值合并赋值)确保简洁初始化,兼容旧环境可替换为 acc[key] = acc[key] || {...};
- 解构 { price, ...rest } 安全分离待聚合字段与分组字段,逻辑解耦清晰。
⚠️ 注意事项:
- 分组键拼接依赖属性值的字符串一致性(如 null/undefined 会转为 "null"/"undefined",建议提前校验);
- 若需去重合并 price(如避免重复数字),可在 push(...price) 后添加 Array.from(new Set(acc[key].price));
- 对于深层嵌套或动态字段场景,可封装为通用函数,接收 keys 和 mergeField 参数。
此方法兼顾性能、可读性与扩展性,是现代 JavaScript 中处理多维分组聚合任务的推荐实践。










