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,需要修正代码得到符合要求的结果。
问题原因与修正代码
核心错误点
forEach方法没有返回值,赋值给headersAsKeys的结果是undefined,自然无法调用forEach方法Array.filter执行后没有将结果赋值回变量,筛选逻辑实际没有生效- 提取内层对象时,把外层和数据绑定的
header字段丢失了,内层grid数据对象本身没有header属性,后续无法取到对应表头 - 求和逻辑没有做初始值处理,直接执行
+=会得到NaN - 存在多余绕路逻辑,不需要提前单独提取所有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
相关产品推荐
相关产品推荐

