问卷响应次数统计代码中计数翻倍而非递增的问题排查
统计问卷问题响应次数的计数异常修复
需求
统计每份问卷中每个问题的各响应出现次数。
问卷数据
每个对象代表一份问卷,最多包含10个问题和5种不同响应。
const allSubmittedSurveysData: {}[] = [ { surveyGUID:'1234', q1ID: '0001', q1Response:'Very Satisfied', q2ID: '0002', q2Response:'Very Happy', q3ID: '0003', q3Response:'Satisfied', q4ID: '0004', q4Response:'Very Satisfied', q5ID: '0005', q5Response:'Very Satisfied', q6ID: '0006', q6Response:'Very Satisfied', q7ID: '0007', q7Response:'Very Satisfied', q8ID: '0008', q8Response:'Very Satisfied', q9ID: '0009', q9Response:'Very Satisfied', q10ID: '0010', q10Response:'Very Satisfied', }, { surveyGUID:'1235', q1ID: '0001', q1Response:'Satisfied', q2ID: '0002', q2Response:'Unhappy', q3ID: '0003', q3Response:'Dissatisfied', q4ID: '0004', q4Response:'Dissatisfied', q5ID: '0005', q5Response:'Very Satisfied', }, { surveyGUID:'1236', q1ID: '0001', q1Response:'Dissatisfied', q2ID: '0002', q2Response:'Neutral', q3ID: '0003', q3Response:'Satisfied', q4ID: '0004', q4Response:'Very Dissatisfied', q5ID: '0005', q5Response:'Very Satisfied', }, ]
现有实现代码
let responseCounts: Record<string, any> = {} allSubmittedSurveysData.forEach((survey: Record<string,any>) => { Object.keys(survey).forEach(key => { if(key!=='surveyGUID') { let questionKey = key.replace('Response', 'ID') let responseKey= key.replace('ID','Response') if(!Object.keys(responseCounts).includes(survey[questionKey])){ responseCounts[survey[questionKey]]={} } if(!Object.keys(responseCounts[survey[questionKey]]).includes(survey[responseKey])){ responseCounts[survey[questionKey]][survey[responseKey]]= 1 } else{ ++responseCounts[survey[questionKey]][survey[responseKey]] } } }) })
预期输出示例
responseCounts= { 0001:{ Very Satisfied:1, Satisfied:1, Dissatisfied:1 }, 0002:{...}, 0003:{...}, // 其他问题的统计结果 }
问题描述
构建responseCounts对象时,每个问题ID对应一个子对象,子对象以响应为键,首次出现赋值为1,后续出现应递增计数。目前if分支逻辑正常,但else分支未实现每次加1,而是将数值翻倍。
问题原因
当前代码遍历问卷对象的所有键(除了surveyGUID),每个问题的qXID和qXResponse都会被处理一次。比如处理q1ID时,会找到对应的q1Response并计数;接着处理q1Response时,又会找到对应的q1ID和同一个响应值再次计数。同一个响应被重复统计两次,所以每次出现都会导致计数翻倍。
修复方案
只遍历以Response结尾的键,这样每个问题只处理一次,避免重复统计:
let responseCounts: Record<string, any> = {} allSubmittedSurveysData.forEach((survey: Record<string, any>) => { // 只处理响应字段,跳过ID和surveyGUID Object.keys(survey).forEach(key => { if (key.endsWith('Response')) { // 从响应键名推导对应的问题ID键名,比如q1Response -> q1ID const questionIdKey = key.replace('Response', 'ID'); const questionId = survey[questionIdKey]; const response = survey[key]; // 初始化问题的统计对象 if (!responseCounts[questionId]) { responseCounts[questionId] = {}; } // 更新响应计数 responseCounts[questionId][response] = (responseCounts[questionId][response] || 0) + 1; } }); });
修复说明
- 筛选出所有以
Response结尾的键,确保每个问题只被处理一次。 - 简化计数逻辑:用
(responseCounts[questionId][response] || 0) + 1替代原有的if-else,既处理首次出现的情况,也处理后续递增的情况,代码更简洁。 - 避免了原代码中同时处理ID和Response键导致的重复统计问题。
测试修复后的代码,会得到符合预期的计数结果,每个响应的出现次数不再翻倍。
内容的提问来源于stack exchange,提问作者user6279105
相关产品推荐
相关产品推荐

