如何将后端返回的对象数组合并为按页码分组的结构化数组?
问题描述
需要将后端返回的对象数组按pageNumber分组,转换为包含页码和对应问题列表的结构化数组。
原始数组
let a = [ { QuestionNo: "1", pageNumber: "1", response: "xyz", question: "What is your Name", publicUrl: null, fieldtype: "Text" }, { QuestionNo: "2", pageNumber: "1", response: "7897897987", question: "Phone no", publicUrl: null, fieldtype: "Phone" }, { QuestionNo: "1", pageNumber: "2", response: "true", question: "Are you employeed?", publicUrl: null, fieldtype: "Checkbox" }, { QuestionNo: "2", pageNumber: "2", response: "2023-03-30T10:27:00.000Z", question: "validity", publicUrl: null, fieldtype: "Datetime" } ];
预期输出
[ { "pageNumber": "1", "Questions": [ { QuestionNo: "1", pageNumber: "1", response: "xyz", question: "What is your Name", publicUrl: null, fieldtype: "Text" }, { QuestionNo: "2", pageNumber: "1", response: "7897897987", question: "Phone no", publicUrl: null, fieldtype: "Phone" } ] }, { "pageNumber": "2", "Questions": [ { QuestionNo: "1", pageNumber: "2", response: "true", question: "Are you employeed?", publicUrl: null, fieldtype: "Checkbox" }, { QuestionNo: "2", pageNumber: "2", response: "2023-03-30T10:27:00.000Z", question: "validity", publicUrl: null, fieldtype: "Datetime" } ] } ]
问题代码
原代码在// *issue here*的else分支存在逻辑错误,会重复添加分组对象:
let finalAnswer = []; let a = [ { QuestionNo: "1", pageNumber: "1", response: "xyz", question: "What is your Name", publicUrl: null, fieldtype: "Text" }, { QuestionNo: "2", pageNumber: "1", response: "7897897987", question: "Phone no", publicUrl: null, fieldtype: "Phone" }, { QuestionNo: "1", pageNumber: "2", response: "true", question: "Are you employeed?", publicUrl: null, fieldtype: "Checkbox" }, { QuestionNo: "2", pageNumber: "2", response: "2023-03-30T10:27:00.000Z", question: "validity", publicUrl: null, fieldtype: "Datetime" } ]; a.forEach((val) => { if (finalAnswer.length > 0) { finalAnswer.filter((v, i) => { if (val.pageNumber === v.pageNumber) { finalAnswer[i].Questions.push(val); } else { // *issue here* finalAnswer.push({ pageNumber: val.pageNumber, Questions: [val] }); } }); } else { finalAnswer.push({ pageNumber: val.pageNumber, Questions: [val] }); } console.log("finalAnswer", JSON.stringify(finalAnswer)); });
错误原因
- 使用
filter遍历finalAnswer时,每遇到不匹配的页码就会执行一次push,导致同一个分组被重复添加 - 逻辑上应该先检查是否存在对应页码的分组,存在则追加,不存在才新增
修复方案
方案一:使用find查找已有分组(逻辑直观)
let finalAnswer = []; let a = [/* 原始数组内容 */]; a.forEach((val) => { // 查找是否已存在当前页码的分组 const existingPage = finalAnswer.find(page => page.pageNumber === val.pageNumber); if (existingPage) { // 存在则将当前问题加入该分组的Questions数组 existingPage.Questions.push(val); } else { // 不存在则新增分组 finalAnswer.push({ pageNumber: val.pageNumber, Questions: [val] }); } }); console.log(JSON.stringify(finalAnswer, null, 2));
方案二:使用对象作为中间映射(性能更优)
适合处理大数据量场景,时间复杂度为O(n):
let a = [/* 原始数组内容 */]; // 先用对象按页码分组,key为pageNumber,value为对应问题数组 const pageMap = a.reduce((map, item) => { if (!map[item.pageNumber]) { map[item.pageNumber] = []; } map[item.pageNumber].push(item); return map; }, {}); // 将映射对象转换为预期的数组格式 const finalAnswer = Object.entries(pageMap).map(([pageNumber, Questions]) => ({ pageNumber, Questions })); console.log(JSON.stringify(finalAnswer, null, 2));
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

