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

JavaScript如何遍历对象数组统计生成按服务分类的状态计数嵌套对象

问题核心原因

  • 你初始化时所有服务共用了同一个nestedObj对象:JS中对象是引用类型,你把同一个对象赋值给所有服务的属性,后续修改任意一个服务的计数,所有服务的计数都会同步变化,这就是你看到所有计数都等于全局总和的根源
  • 初始化逻辑冗余,统计阶段的双层for循环完全没必要,遍历一次数组就可以完成初始化+统计,效率更高
  • 统计代码存在语法错误:countsObj[status = countsObj[status] + 1 缺少右方括号,正确写法是countsObj[status] = countsObj[status] + 1

正确实现代码

// 注意原数据里的服务名、状态值需要加引号,否则会被识别为变量报错
const dataArr = [
    {service: 's1', status: 'ready'},
    {service: 's2', status: 'ready'},
    {service: 's1', status: 'retired'},
    {service: 's3', status: 'retired'},
    {service: 's2', status: 'ready'}
];

const statusByServiceObj = {};
dataArr.forEach(ele => {
    // 当前服务未初始化时,新建独立的计数对象,初始值为0
    if (!statusByServiceObj[ele.service]) {
        statusByServiceObj[ele.service] = {
            ready: 0,
            retired: 0
        };
    }
    // 对应状态计数加1
    statusByServiceObj[ele.service][ele.status]++;
});

运行后statusByServiceObj输出结果完全符合需求:

{
  s1: { ready: 1, retired: 1 },
  s2: { ready: 2, retired: 0 },
  s3: { ready: 0, retired: 1 }
}

相关最佳实践

  • 注意引用类型的引用共享问题:不要复用同一个对象/数组赋值给多个属性,每次需要独立值的时候要新建对象,避免多个属性指向同一块内存地址
  • 优先用单次遍历完成聚合统计:不需要分开做初始化、统计两次遍历,也不需要嵌套循环遍历已有属性,直接在单次遍历中判断是否存在对应键即可,时间复杂度只有O(n),效率更高
  • 数组聚合统计场景可以用Array.reduce写出更简洁的代码,示例:
const statusByServiceObj = dataArr.reduce((acc, curr) => {
    if (!acc[curr.service]) {
        acc[curr.service] = { ready: 0, retired: 0 };
    }
    acc[curr.service][curr.status]++;
    return acc;
}, {});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:45:02