You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:07:04