如何基于两个现有数组的值创建按grid_row_id分组的结构化对象数组?
解决按grid_row_id分组格式化数据的问题
你的核心需求是将dataArr中相同grid_row_id的条目合并成一个对象,用tableCols中对应id的header作为键、数值化的data作为值。原来的代码问题在于没有按grid_row_id分组,而是每个条目都生成一个对象,还因为newObj是全局变量导致所有元素都指向同一个对象,最终结果不符合预期。
优化后的解决方案代码
// 先构建tableCols的id到header的映射表,提升查找效率 const colMap = tableCols.reduce((map, col) => { map[col.id] = col.header; return map; }, {}); // 使用reduce按grid_row_id分组并构建目标对象 const formattedData = Object.values(dataArr.reduce((grouped, row) => { // 取出当前行的rowId和对应的header const rowId = row.grid_row_id; const header = colMap[row.grid_col_id]; // 如果该rowId还没有分组,初始化一个空对象 if (!grouped[rowId]) { grouped[rowId] = {}; } // 给当前分组对象添加键值对,data转成数值类型 grouped[rowId][header] = Number(row.data); return grouped; }, {}));
关键步骤解释
构建
colMap映射表:
这一步是把tableCols转换成{ [colId]: header }的结构,这样后续查找grid_col_id对应的header时,不用每次都遍历整个tableCols数组,时间复杂度从O(n*m)降到O(n),数据量大时性能提升明显。用
reduce分组构建对象:reduce的累加器grouped是一个临时对象,键是grid_row_id,值是对应行的格式化对象。- 遍历
dataArr的每个条目时,先检查当前grid_row_id是否已经在grouped中:如果没有,就初始化一个空对象;如果已经存在,就直接往这个对象里添加新的键值对。 - 最后用
Object.values()把grouped对象的所有值提取出来,转换成你需要的数组格式。
和原代码的对比改进
- 原代码的
newObj是全局变量,每次循环都会覆盖它的内容,导致所有formattedData的元素都指向同一个对象,最终结果全部是最后一次循环的内容。 - 新代码通过
reduce自然实现了分组,每个grid_row_id对应一个独立的对象,不会出现引用覆盖的问题。 - 引入
colMap避免了嵌套循环,提升了代码效率和可读性。
内容的提问来源于stack exchange,提问作者Beginner_Hello
相关产品推荐
相关产品推荐

