Node.js中如何实现两个对象间的通用条件校验
问题:实现通用的科目校验与总分统计逻辑
我需要在Node.js代码中统计各科目总分并存入marks对象,同时根据info中的规则(科目名称+对应等级)校验res.edu中的每个对象,匹配则将信息存入数组。但当前代码每次info新增科目都要手动加else if分支,想实现通用逻辑,无需随info结构变更修改代码。
info可动态变更,例如:
let info = {"math": 1, "science": 2} // 或 let info = {"math": 1, "science": 2, "history": 1, arts: 1}
原代码如下:
let res = { edu: [ { name: "math", level: 1, marks: 50, part: 1, }, { name: "math", level: 1, marks: 57, part: 2, }, { name: "science", level: 2, marks: 70, part: 1, }, ], age: 20, name: "abc", } let info = { math: 1, science: 2, history: 1 } const func = () => { var marks = {} let subject = Object.keys(info) subject.forEach((subjName, index) => { marks[subjName] = 0 }) console.log("marks = ", marks) var consolidatedInfo = [] res.edu.forEach(function (subj) { if (subj.name === Object.keys(info)[0] && subj.level === info[Object.keys(info)[0]]) { marks[subj.name] += subj.marks const eachSubjPartInfo = { name: subj.name, level: subj.level, marks: subj.marks, part: subj.part, } consolidatedInfo.push(eachSubjPartInfo) console.log("marks: ", marks) } else if (subj.name === Object.keys(info)[1] && subj.level === info[Object.keys(info)[1]]) { marks[subj.name] += subj.marks const eachSubjPartInfo = { name: subj.name, level: subj.level, marks: subj.marks, part: subj.part, } consolidatedInfo.push(eachSubjPartInfo) console.log("marks: ", marks) } else if (subj.name === Object.keys(info)[2] && subj.level === info[Object.keys(info)[2]]) { marks[subj.name] += subj.marks const eachSubjPartInfo = { name: subj.name, level: subj.level, marks: subj.marks, part: subj.part, } consolidatedInfo.push(eachSubjPartInfo) console.log("marks: ", marks) } }) console.log("consolidatedInfo = ", consolidatedInfo) console.log("marks = ", marks) } func()
我曾考虑用switch,但本质和if else一样,请问怎么实现通用逻辑?
解决方案
核心思路是直接利用info对象的键值对做匹配判断,不需要枚举每个索引。具体优化如下:
优化后的代码
let res = { edu: [ { name: "math", level: 1, marks: 50, part: 1 }, { name: "math", level: 1, marks: 57, part: 2 }, { name: "science", level: 2, marks: 70, part: 1 }, // 可新增符合info规则的科目测试 { name: "history", level: 1, marks: 85, part: 1 }, ], age: 20, name: "abc", } let info = { math: 1, science: 2, history: 1 } const func = () => { // 简洁初始化marks:所有科目初始分数为0 const marks = Object.fromEntries(Object.keys(info).map(subj => [subj, 0])) console.log("初始marks = ", marks) const consolidatedInfo = [] res.edu.forEach(subj => { // 通用匹配逻辑:检查科目是否在规则内,且等级匹配 if (info.hasOwnProperty(subj.name) && subj.level === info[subj.name]) { // 累加对应科目分数 marks[subj.name] += subj.marks // 快速复制所需字段到数组 consolidatedInfo.push({ ...subj }) console.log("更新后的marks: ", marks) } }) console.log("consolidatedInfo = ", consolidatedInfo) console.log("最终marks = ", marks) } func()
关键逻辑说明
- 初始化总分对象:用
Object.fromEntries替代原forEach循环,一行代码生成所有科目初始分数为0的marks对象,更简洁高效。 - 通用匹配判断:通过
info.hasOwnProperty(subj.name)确认当前科目在规则内,再对比等级是否符合info[subj.name],不管info新增多少科目,判断逻辑都无需修改。 - 简化对象复制:用对象展开运算符
{ ...subj }直接复制原对象的所有属性,避免重复手动定义字段,后续res.edu字段变更时也不用调整这部分代码。
内容的提问来源于stack exchange,提问作者Renee
相关产品推荐
相关产品推荐

