如何实现基于动态eventList的API响应重排与缺失补全?
问题
现有eventList数组与API返回的response数组,需要按eventList的顺序循环重排response:
- 以
eventList的元素顺序为一组,依次放入对应eventTitle的对象,直至处理完所有response元素 - 若某组中存在缺失的
eventTitle,需用id=0、对应eventTitle的空对象补全
示例
输入:
let eventList = ["XM1", "XM2", "XM3"]; let response = [ {"id": 1, "eventTitle": "XM1"}, {"id": 2, "eventTitle": "XM3"}, {"id": 3, "eventTitle": "XM2"}, {"id": 4, "eventTitle": "XM2"}, ]
处理后结果:
let sortResponse = [ {"id": 1, "eventTitle": "XM1"}, {"id": 3, "eventTitle": "XM2"}, {"id": 2, "eventTitle": "XM3"}, {"id": 0, "eventTitle": "XM1"}, {"id": 4, "eventTitle": "XM2"}, {"id": 0, "eventTitle": "XM3"}, ]
当前代码仅支持长度为3的eventList,需实现适配任意长度eventList的动态方案。
当前非动态代码
let sortResponse = [] if (eventList.length === 3 && response.length > 0) { let fil1 = response.filter(function (el) { return el.eventTitle === eventList[0]; }); let fil2 = response.filter(function (el) { return el.eventTitle === eventList[1]; }); let fil3 = response.filter(function (el) { return el.eventTitle === eventList[2]; }); let obj = { id: 0, eventTitle: "" }; let obj1 = { id: 0, eventTitle: "" }; //check if fil1 has most elements and use it to iterate through each fil1 and push fil2 and fil3 if (fil1.length >= fil2.length && fil1.length >= fil3.length) { for (let j = 0; j < fil1.length; j++) { sortResponse.push(fil1[j]); if (!fil2[j]) { obj.eventTitle = eventList[1]; } sortResponse.push(fil2[j] ? fil2[j] : obj); if (!fil3[j]) { obj1.eventTitle = eventList[2]; } sortResponse.push(fil3[j] ? fil3[j] : obj1); } } //check if fil2 has most elements and use it to iterate through each fil2 and push fil1 and fil3 else if (fil2.length >= fil1.length && fil2.length >= fil3.length) { for (let j = 0; j < fil2.length; j++) { if (!fil1[j]) { obj.eventTitle = eventList[0]; } sortResponse.push(fil1[j] ? fil1[j] : obj); sortResponse.push(fil2[j]); if (!fil3[j]) { obj1.eventTitle = eventList[2]; } sortResponse.push(fil3[j] ? fil3[j] : obj1); } } //check if fil3 has most elements and use it to iterate through each fil3 and push fil1 and fil2 else if (fil3.length >= fil1.length && fil3.length >= fil2.length) { for (let j = 0; j < fil3.length; j++) { if (!fil1[j]) { obj.eventTitle = eventList[0]; } sortResponse.push(fil1[j] ? fil1[j] : obj); if (!fil2[j]) { obj1.eventTitle = eventList[1]; } sortResponse.push(fil2[j] ? fil2[j] : obj1); sortResponse.push(fil3[j]); } } }
动态实现方案
思路
- 按
eventTitle对response进行分组,每个eventTitle对应一个存储对应对象的数组 - 找出所有分组中长度最大的那个,确定需要循环的轮数
- 每一轮按照
eventList的顺序,依次从对应分组中取出第n个元素;若不存在则生成id=0、对应eventTitle的补全对象 - 将每一轮的元素依次加入结果数组
代码实现
function sortResponseByEventList(eventList, response) { const sortResponse = []; if (!eventList.length || !response.length) return sortResponse; // 按eventTitle分组,生成键为标题、值为对应对象数组的映射 const eventGroups = eventList.reduce((groups, title) => { groups[title] = response.filter(item => item.eventTitle === title); return groups; }, {}); // 计算最长分组的长度,确定循环轮数 const maxRound = Math.max(...eventList.map(title => eventGroups[title].length)); // 逐轮按eventList顺序填充元素 for (let round = 0; round < maxRound; round++) { for (const title of eventList) { const targetItem = eventGroups[title][round]; // 存在则直接加入,不存在则生成补全对象 sortResponse.push(targetItem ? targetItem : { id: 0, eventTitle: title }); } } return sortResponse; } // 测试示例 const eventList = ["XM1", "XM2", "XM3"]; const response = [ {"id": 1, "eventTitle": "XM1"}, {"id": 2, "eventTitle": "XM3"}, {"id": 3, "eventTitle": "XM2"}, {"id": 4, "eventTitle": "XM2"}, ]; const result = sortResponseByEventList(eventList, response); console.log(result);
代码说明
- 动态分组:通过
reduce和filter实现自动分组,无需硬编码多个分组变量,适配任意长度的eventList - 自适应轮数:通过
Math.max计算所有分组的最大长度,自动确定循环次数,无需手动判断哪个分组最长 - 通用补全逻辑:遍历
eventList时直接判断对应位置元素是否存在,不存在则生成标准补全对象,避免重复的条件判断
内容的提问来源于stack exchange,提问作者Antanio D
相关产品推荐
相关产品推荐

