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

JavaScript处理嵌套对象数组按规则分组求和生成目标数组

JS数组筛选聚合问题修复

(这是此前同类问题的更复杂场景)

基础数据

现有结构如下的数组originalArrayData:

originalArrayData = [{
    "16": {
        "id": 22,
        "grid_row_id": 5,
        "grid_col_id": 16,
        "data": "10",
        "created_at": "rertte",
        "error_mgs": null
    },
    "header": "BUTTERFLY HEADER",
    "id": 5
},
{
    "17": {
        "id": 31,
        "grid_row_id": 9,
        "grid_col_id": 16,
        "data": "14",
        "created_at": "rtyhtyjtdyj",
        "error_mgs": null
    },
    "header": "BUTTERFLY HEADER",
    "id": 6
},
{
    "18": {
        "id": 35,
        "grid_row_id": 9,
        "grid_col_id": 12,
        "data": "55",
        "created_at": "thrtuhrs",
        "error_mgs": null
    },
    "header": "PARROT HEADER",
    "id": 6
},
{
    "19": {
        "id": 36,
        "grid_row_id": 9,
        "grid_col_id": 12,
        "data": "31",
        "created_at": "rtyhtyjtdyj",
        "error_mgs": null
    },
    "header": "PARROT HEADER",
    "id": 7
},
{
    "20": {
        "id": 36,
        "grid_row_id": 9,
        "grid_col_id": 14,
        "data": "31",
        "created_at": "rtyhtyjtdyj",
        "error_mgs": null
    },
    "header": "OTHER HEADER",
    "id": 7
}...........

另有一个ID数组arrayOfIds,数组长度不固定(可为1、2、3等任意值,元素为随机数字),示例值如下:

arrayOfIds: [16 , 12]

需求说明

  • 筛选出grid_col_id存在于arrayOfIds中的所有数据项,排除不符合的项
  • 将每项的header值转为小写、去除空格后作为新对象的键
  • 对相同键对应项的data值求和,作为键的对应值
  • 最终返回的数组中必须包含硬编码的固定键值对"category": "None"

目标输出示例

[{ "butterflyheader": 24, "parrotheader": 86, "category": "None"}]

逻辑解释

上述示例中前2项grid_col_id为16(在arrayOfIds中)、header相同,data值10+14=24,对应键butterflyheader值为24;第三、四项grid_col_id为12(在arrayOfIds中)、header相同,data值55+31=86,对应键parrotheader值为86;最后一项grid_col_id为14不在arrayOfIds中,故排除。

现有问题

原有实现代码如下:

// 提取原数组中所有内层嵌套对象
let tableDataFiltered = originalArrayData.map(item => 
    Object.values(item).filter(item => typeof item === "object")
).flat()

// 筛选grid_col_id符合要求的项
tableDataFiltered.filter(item => arrayOfIds.includes(item.grid_col_id))

// 生成用于键名的处理后header值
let headersAsKeys = tableDataFiltered.forEach(item => {
    item.header.toLowerCase().split(' ').join(''))
})

Object.values(tableDataFiltered.reduce((acc, curr) => {
    acc[curr.category] = 'None';
    headersAsKeys.forEach(key => {
        acc[curr.category][key] += curr[key];
    })
    return acc;
}, {}));

运行后抛出错误:headersAsKeys.forEach is not a function,需要修正代码得到符合要求的结果。

问题原因与修正代码

核心错误点

  1. forEach方法没有返回值,赋值给headersAsKeys的结果是undefined,自然无法调用forEach方法
  2. Array.filter执行后没有将结果赋值回变量,筛选逻辑实际没有生效
  3. 提取内层对象时,把外层和数据绑定的header字段丢失了,内层grid数据对象本身没有header属性,后续无法取到对应表头
  4. 求和逻辑没有做初始值处理,直接执行+=会得到NaN
  5. 存在多余绕路逻辑,不需要提前单独提取所有header键,遍历过程中直接处理即可

修正后可运行代码

// 初始化结果对象,先写入固定的category字段
const resObj = { category: "None" };

originalArrayData.forEach(item => {
    // 找到当前项里存网格数据的内层对象(排除null、排除字符串/数字类型值)
    const gridItem = Object.values(item).find(val => typeof val === "object" && val !== null);
    // 不符合grid_col_id要求的直接跳过
    if (!arrayOfIds.includes(gridItem.grid_col_id)) return;
    // 处理header为目标键名:转小写+移除所有空格
    const key = item.header.toLowerCase().replaceAll(' ', '');
    // 累加data值,注意原data是字符串类型需要转数字,首次出现的键初始值设为0
    resObj[key] = (resObj[key] || 0) + Number(gridItem.data);
})

// 按要求把结果包在数组里返回
const finalResult = [resObj];

用示例数据运行上述代码,得到的结果和目标输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:31:04