如何在JS中按name和status过滤对象数组并统计数量
问题描述
现有如下数组数据:
[ {service: { name: "Home" },status: "Generated", feeCharged:{id:1,fee:2}}, {service: { name: " Photography" },status: "requested",feeCharged:{id:2,fee:24}}, {service: { name: "Electrical" },status: "requested",feeCharged:{id:6,fee:42}}, {service: { name: "Electrical" },status: "Completed",feeCharged:{id:66,fee:23} }, {service: { name: " Photography" },status: "Completed",feeCharged:{id:78,fee:11}}, {service: { name: "Home" },status: "Generated",feeCharged:{id:45,fee:234}}, {service: { name: "Electrical" }, status: "requested",feeCharged:{id:77,fee:3} }, {service: { name: "Electrical" }, status: "requested",feeCharged:{id:4,fee:33} } ]
需要按service.name和status两个字段分组,合并相同组合的对象并添加count统计数量,最终期望结果:
[ { name: "Home", status: "Generated", count: 2 }, { name: "Photography", status: "requested", count: 1 }, { name: "Photography", status: "Completed", count: 1 }, { name: "Electrical", status: "requested", count: 3 }, { name: "Electrical", status: "Completed", count: 1 } ]
尝试的代码未达到预期:
let answer = []; data.forEach((x) => { if (!answer.some((y) => y.name === x.service.name)) { let newAnswer = {}; newAnswer.name = x.service.name; newAnswer.value = 1; answer.push(newAnswer); } else { let existAnswer = answer.find((y) => y.name === x.service.name); existAnswer.value++; } });
问题分析
你当前的代码只依据service.name进行分组统计,没有将status纳入分组条件,导致同一service.name下不同status的项会被错误合并,自然得不到预期结果。另外原数据中部分service.name带有前置空格,需要做去除处理以匹配期望结果。
解决方案
可以使用Array.reduce()方法实现分组统计,同时处理名称的空格问题:
const data = [ {service: { name: "Home" },status: "Generated", feeCharged:{id:1,fee:2}}, {service: { name: " Photography" },status: "requested",feeCharged:{id:2,fee:24}}, {service: { name: "Electrical" },status: "requested",feeCharged:{id:6,fee:42}}, {service: { name: "Electrical" },status: "Completed",feeCharged:{id:66,fee:23} }, {service: { name: " Photography" },status: "Completed",feeCharged:{id:78,fee:11}}, {service: { name: "Home" },status: "Generated",feeCharged:{id:45,fee:234}}, {service: { name: "Electrical" }, status: "requested",feeCharged:{id:77,fee:3} }, {service: { name: "Electrical" }, status: "requested",feeCharged:{id:4,fee:33} } ]; // 用reduce生成分组统计的对象,键为name和status的组合 const grouped = data.reduce((acc, item) => { const name = item.service.name.trim(); // 去除名称前后空格 const status = item.status; const key = `${name}-${status}`; // 生成唯一分组键 if (acc[key]) { acc[key].count++; } else { acc[key] = { name, status, count: 1 }; } return acc; }, {}); // 将分组对象转为数组 const answer = Object.values(grouped); console.log(answer);
代码说明
- 分组键生成:通过
name和status拼接成唯一字符串作为键,确保同一名称+状态的项被归为一组。 - 空格处理:使用
trim()去除service.name前后的空格,匹配期望结果中的名称格式。 - 统计逻辑:遍历数组时,若分组已存在则计数+1,否则创建新的分组项并初始化计数为1。
- 结果转换:通过
Object.values()将分组对象转为最终的数组格式。
内容的提问来源于stack exchange,提问作者someone
相关产品推荐
相关产品推荐

