Search code examples
javascriptnode.jsreactjsobjectcomparison

How to make a condition check between two objects generic in node js?


In the below code I am trying count the total marks for each subject and storing them in marks object. I am checking if each obj in edu is a part of info based on subject name(name) and subject level(level). If it matches I am putting everything in an array.

Here, in function 'func' every time a subject gets added to info I will have to add another 'else if' to check. I don't want to always add this condition check.

I would like to make it generic, say, my info becomes:

let info = {"math": 1, "science": 2}
or
let info = {"math": 1, "science": 2, "history": 1, arts: 1}

I don't want to remove or add condition check. I want the check between the response(edu) and info to be done without dependency. Only based on info the check is to happen.

This is in node js. How do I do it? I though of switch but that is the same as 'if else'.

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()



Solution

  • you can use the logic info[name] === level in each iteration to dynamically check and only add if it satisfies. No need to convert to an array and then check

    i used array reduce. To create initial object with each subject 0 marks i used Object.fromEntries(Object.keys(info).map(k => [k,0]))

    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 marksAccumulator = Object.fromEntries(Object.keys(info).map(k => [k,0]))
    
    const result = res.edu.reduce((acc,{name,level,marks,part}) => {
      if(info?.[name] === level){
        acc.marksAccumulator[name] += marks
        acc.consolidated.push({name,level,marks,part})
      }
      return acc
    },{marksAccumulator,consolidated:[]})
    
    console.log(result)

    From result you can get the required data as result.consolidated and so on

    you can also do without destructuring the current element in iteration

    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 marksAccumulator = Object.fromEntries(Object.keys(info).map(k => [k,0]))
    
    const result = res.edu.reduce((acc,curr) => {
      if(info?.[curr.name] === curr.level){
        acc.marksAccumulator[curr.name] += curr.marks
        acc.consolidated.push(curr)
      }
      return acc
    },{marksAccumulator,consolidated:[]})
    
    console.log(result)