javascript对扁平数组分组聚合的核心是用reduce配合map/object,关键在明确分组依据和聚合逻辑:单字段计数、多字段组合键求和/平均、map支持对象等复杂key、封装通用函数提升复用,并注意数据清洗。

JavaScript 对后端返回的扁平数组做分组与聚合统计,核心是用 reduce 或配合 Map / Object 构建分组结构,再对每组数据执行求和、计数、平均值等操作。关键不在“多复杂”,而在“分组依据”和“聚合逻辑”是否清晰。
按单个字段分组并统计数量
比如后端返回用户订单列表,想按 status(如 "paid"、"pending")统计各状态订单数:
const orders = [
{ id: 1, status: 'paid', amount: 99 },
{ id: 2, status: 'pending', amount: 45 },
{ id: 3, status: 'paid', amount: 120 }
];
const countByStatus = orders.reduce((acc, order) => {
acc[order.status] = (acc[order.status] || 0) + 1;
return acc;
}, {});
// 结果:{ paid: 2, pending: 1 }
按多个字段分组并聚合数值(如求和、平均)
若需按 category 和 year 分组,并统计总销售额和平均单价:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先用组合键(如
`${cat}-${year}`)作为分组标识 - 每组维护
sum、count、total等中间状态 - 最后可映射为更易读的结构(如数组或带元信息的对象)
const sales = [
{ category: 'book', year: 2023, price: 35 },
{ category: 'book', year: 2023, price: 42 },
{ category: 'tech', year: 2023, price: 89 }
];
const grouped = sales.reduce((acc, item) => {
const key = `${item.category}-${item.year}`;
if (!acc[key]) {
acc[key] = { category: item.category, year: item.year, total: 0, count: 0 };
}
acc[key].total += item.price;
acc[key].count += 1;
return acc;
}, {});
// 转成数组并计算平均值
const result = Object.values(grouped).map(g => ({
...g,
avg: Number((g.total / g.count).toFixed(2))
}));
// [{ category: 'book', year: 2023, total: 77, count: 2, avg: 38.5 }, ...]
用 Map 实现更安全的分组(支持任意类型 key)
当分组依据是对象、日期或 Symbol 时,普通对象 key 会自动转字符串,丢失信息。此时用 Map 更可靠:
const data = [
{ user: { id: 1, name: 'Alice' }, score: 85 },
{ user: { id: 1, name: 'Alice' }, score: 92 },
{ user: { id: 2, name: 'Bob' }, score: 76 }
];
const map = new Map();
data.forEach(item => {
const { user, score } = item;
if (!map.has(user)) {
map.set(user, { user, sum: 0, count: 0 });
}
const group = map.get(user);
group.sum += score;
group.count += 1;
});
// 注意:Map 的 key 是引用相等,确保传入的是同一对象实例
// 否则需先序列化或自定义唯一标识(如 user.id)
封装通用分组聚合函数(提升复用性)
把重复逻辑抽成函数,支持灵活传入分组规则和聚合操作:
function groupAndAggregate(arr, getKey, aggregateFn) {
return arr.reduce((acc, item) => {
const key = typeof getKey === 'function' ? getKey(item) : item[getKey];
if (!acc[key]) acc[key] = [];
acc[key].push(item);
return acc;
}, {}).map((items, key) => ({
key,
items,
...aggregateFn(items)
}));
}
// 使用示例:按 status 分组,统计数量和总金额
const result = groupAndAggregate(orders, 'status', items => ({
count: items.length,
totalAmount: items.reduce((sum, o) => sum + o.amount, 0)
}));
不复杂但容易忽略:后端返回的数据可能含空值、类型不一致(如 "2023" 字符串 vs 2023 数字),建议在分组前用 filter 清洗或用 ?? / || 提供默认值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










