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

如何迭代嵌套数组对象,整理地点维度的客户状态统计数据?

嵌套数组的地点统计重构

你有如下的嵌套对象数组(先修正了原代码里的语法错误,比如缺冒号、逗号):

let array = [
  {
    key: 'Newcastle',
    values: [
      {
        key: 'ID1000',
        values: [
          {name: 'Jeff', cust_id: "ID1000", status: 'sold'},
          {name: 'Jeff', cust_id: "ID1000", status: 'pending'},
        ]
      },
      {
        key: 'ID2000',
        values: [
          {name: 'Bob', cust_id: "ID2000", status: 'sold'}
        ]
      }
    ]
  },
  {
    key: 'London',
    values: [
      {
        key: 'ID3000',
        values: [
          {name: 'Gary', cust_id: "ID3000", status: 'sold'},
        ]
      },
      {
        key: 'ID4000',
        values: [
          {name: 'Mary', cust_id: "ID4000", status: 'interest'},
          {name: 'Mary', cust_id: "ID4000", status: 'interest'},
          {name: 'Mary', cust_id: "ID4000", status: 'pending'},
        ]
      }
    ]
  }
];

你希望将其重构为按地点统计客户数及各状态次数的格式:

[
  {Location: 'Newcastle', customers: 2, sold: 2, pending: 1, interest: 0},
  {Location: 'London', customers: 2, sold: 1, pending: 1, interest: 2}
]

你当前尝试的代码遇到了问题,比如forEach无法正确返回统计值,多层嵌套循环导致计数混乱:

function transform(array) {
  let arr = []
  array.forEach(function(x) {
    function soldCount() {
      x.values.forEach(function(x) {
        let sold = x.values.forEach(function(x) {
          let soldTrue = 0
          if (x.status === "sold") {
            soldTrue++
          }
          console.log(soldTrue)
          if (soldTrue > 0) {
            return soldTrue
          }
        })
      })
    }
    let obj = {
      location: x.key,
      customers: x.values.length,
      sold: soldCount()
    }
    arr.push(obj)
  })
  return arr
}

问题分析

你的核心问题在于:

  1. forEach本身不返回任何值(默认返回undefined),所以你在soldCount里用forEach尝试返回计数是行不通的;
  2. 嵌套forEach里的变量作用域有问题,每次循环都会重置soldTrue,根本无法实现累加;
  3. 只单独处理了sold状态,没有统一的逻辑去统计pending和interest,扩展性差。

解决方案:用reduce+map实现高效统计

reduce是处理这类累加统计场景的最优工具,结合map可以快速把每个地点转换为我们需要的统计对象。下面是完整的实现:

function transform(array) {
  return array.map(locationItem => {
    // 初始化当前地点的统计模板
    const stats = {
      Location: locationItem.key,
      customers: locationItem.values.length,
      sold: 0,
      pending: 0,
      interest: 0
    };

    // 遍历每个客户的所有订单,累加状态计数
    locationItem.values.forEach(customer => {
      customer.values.forEach(order => {
        // 只要状态是我们定义的类型,就对应累加
        if (stats.hasOwnProperty(order.status)) {
          stats[order.status]++;
        }
      });
    });

    return stats;
  });
}

// 测试执行
const result = transform(array);
console.log(result);

代码解释

  1. 外层map:遍历每个地点对象,把每个地点直接转换为目标统计格式;
  2. 初始化统计对象:先填好地点名称、客户数(直接取values的长度,因为每个元素对应一个独立客户),并把三个状态的初始计数设为0;
  3. 嵌套遍历订单:先遍历每个客户的订单数组,再遍历每个订单,根据订单的status字段,对应累加统计对象里的计数;
  4. 返回统计结果:每个地点处理完成后,把统计对象加入最终结果数组。

如果想让代码更紧凑,也可以用嵌套reduce来替代forEach,逻辑是完全一致的:

function transform(array) {
  return array.map(locationItem => {
    // 用reduce累加所有订单的状态计数
    const statusStats = locationItem.values.reduce((total, customer) => {
      return customer.values.reduce((counts, order) => {
        counts[order.status]++;
        return counts;
      }, total);
    }, { sold: 0, pending: 0, interest: 0 });

    // 合并基础信息和状态统计
    return {
      Location: locationItem.key,
      customers: locationItem.values.length,
      ...statusStats
    };
  });
}

这个版本用reduce的累加特性来统计状态次数,最后用对象展开运算符...把状态统计和基础信息合并,代码更简洁。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:45:26