Home > Software engineering >  How to fetch sum of value in an object?
How to fetch sum of value in an object?

Time:09-22

254:{
  Term 1:{   
       0:{id:1,Students: 29},
       1:{id:1,Students: 20},
       2:{id:1,Students: 11}
   }
   Term 2:{   
       0:{id:1,Students: 9},
       1:{id:1,Students: 10},
       2:{id:1,Students: 22}
   }
}
251:{
  Term 1:{   
       0:{id:1,Students: 2},
       1:{id:1,Students: 5},
       2:{id:1,Students: 10}
   }
}

OUTPUT should be like -
For 254 - Total count of student should be cumulative of all the term 101
For 251 - Total count of student should be cumulative of all the term 17

254 and 251 is classID. So, in one class there are multiple terms and I need to fetch total student count for all the term in that class.

I tried using reduce but not getting expected output.

this.progressReportList = data -> in this list I am getting data 
this.progressReportList.reduce((acc, ele) => {
          console.log('ele : ', ele)
          return acc   parseInt(ele.Students)
        }, 0)

Please advice!

CodePudding user response:

Your structure means that you need to do multiple steps, including multiple calls to Object.entries / Object.values .... and there are also two reduce calls in there.

const input = {
  254:{
    "Term 1":{   
         0:{id:1,Students: 29},
         1:{id:1,Students: 20},
         2:{id:1,Students: 11}
     },
     "Term 2":{   
         0:{id:1,Students: 9},
         1:{id:1,Students: 10},
         2:{id:1,Students: 22}
     }
  },
  251:{
    "Term 1":{   
         0:{id:1,Students: 2},
         1:{id:1,Students: 5},
         2:{id:1,Students: 10}
     }
  }
}

const result = Object.entries(input).reduce( (acc, [id,terms]) => {
    acc[id] = Object.values(terms) // Get all the terms
                    .flatMap(x => Object.values(x)) // flatten it out
                    .reduce( (sum, x) => sum  = x.Students, 0); // sum the students
    
    return acc;
},{})

console.log(result)

CodePudding user response:

You can use some Object API instead.

Like Object.keys(), Object.values() Or Object.entries()

// iterate through key-value gracefully
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

CodePudding user response:

Observation : Your JSON object is not valid as per the object posted in a post. That might be a typo but I am just informing you.

Solution : You can simply achieve that by using Object.keys() to iterate over an nested object keys and with the help of Array.reduce().

Live Demo :

const obj = {
  254:{
    "Term 1":{   
      0:{id:1,Students: 29},
      1:{id:1,Students: 20},
      2:{id:1,Students: 11}
    },
    "Term 2":{   
      0:{id:1,Students: 9},
      1:{id:1,Students: 10},
      2:{id:1,Students: 22}
    }
  },
  251:{
    "Term 1":{   
      0:{id:1,Students: 2},
      1:{id:1,Students: 5},
      2:{id:1,Students: 10}
    }
  }
};

const res = {};

Object.keys(obj).forEach(key => {
  res[key] = 0;
  Object.keys(obj[key]).forEach(k => {
    res[key]  = Object.values(obj[key][k]).map(element => element.Students).reduce((a, b) => a   b , 0);
  })
});

console.log(res);

  • Related