JavaScript动态计算科目CQ/MCQ总分并存储变量的问题解决
科目分数动态计算问题
需求说明
持有存储各科目分数的对象,核心需求是动态计算所有科目1st_CQ与1st_MCQ的第一部分总分,再计算2nd_MCQ与2nd_CQ的第二部分总分,部分科目(例如英语)不存在MCQ分数项。
分数对象定义如下:
const subNums = { english_1st_CQ : 24, english_2nd_CQ: 24, math_1st_CQ: 40, math_1st_MCQ: 10, math_2nd_CQ:35, math_2nd_MCQ:10, // ..... }
预先定义了科目配置数组,实现思路为遍历所有科目配置项,将第一、第二部分的对应分数传入计算函数,由函数返回对应总分。
配置数组定义如下:
const subject = [ { sub: "english", first: { CQ1st: "english_1st_CQ", MCQ1st: undefined, }, second: { CQ1st: "english_2nd_CQ", MCQ1st: undefined, }, }, { sub: "math", first: { CQ1st: "math_1st_CQ", MCQ1st: "math_1st_MCQ", }, second: { CQ1st: "math_2nd_CQ", MCQ1st: "math_2nd_MCQ", }, }, ]
注:原配置数组存在语法错误,english配置项缺少闭合花括号,上述代码已修正该笔误。
现存问题
- 运行报错:使用
[sub.sub] =的解构写法会抛出错误:number 32 is not iterable (cannot read property Symbol(Symbol.iterator)),无法将计算得到的总分正确存入变量 - 预期输出:按科目名称映射总分,得到形如
{english: 48, math_1st: 50, math_2nd:45}的结构
当前出错的实现代码:
const subTotal = subject.map((sub: any) => { let obj; [sub.sub] = calculateTotal(subNums[sub.first.CQ1st], rest[sub.first.MCQ1st]); });
报错原因
- 数组解构要求等号右侧必须是可迭代对象(比如数组),但
calculateTotal返回的是单个数字类型值,不支持迭代,因此触发类型错误 map方法遍历后返回的是数组,和预期的键值对对象结构不匹配- 现有逻辑仅处理了第一部分分数的计算,遗漏了第二部分分数逻辑,且未处理MCQ项为
undefined的边界情况(不存在的分数项应按0计算) - 代码中引用了未定义的
rest变量,取值应为subNums对象下的对应属性
修复代码
首先实现单部分总分计算函数,自动处理分数不存在的场景:
const calculateTotal = (cqScore?: number, mcqScore?: number): number => { // 不存在的分数默认按0计算 return (cqScore ?? 0) + (mcqScore ?? 0) }
遍历配置项生成目标结果对象:
const subTotal: Record<string, number> = {} subject.forEach(sub => { // 无MCQ的科目(如英语),直接合并两部分CQ为总分 if (!sub.first.MCQ1st && !sub.second.MCQ1st) { subTotal[sub.sub] = calculateTotal(subNums[sub.first.CQ1st], subNums[sub.second.CQ1st]) return } // 有MCQ的科目(如数学),分别计算第一、第二部分总分 subTotal[`${sub.sub}_1st`] = calculateTotal(subNums[sub.first.CQ1st], subNums[sub.first.MCQ1st]) subTotal[`${sub.sub}_2nd`] = calculateTotal(subNums[sub.second.CQ1st], subNums[sub.second.MCQ1st]) })
运行后得到的结果完全符合预期:
{ english: 48, math_1st: 50, math_2nd: 45 }
内容的提问来源于stack exchange,提问作者Fathe
相关产品推荐
相关产品推荐

