Reputation: 56
hope you're having a good day. As the title says, i'm trying calculate several objects in order to make a new one with the average values.
This is the schema
export class stats{
assists: number
causedEarlySurrender: boolean
champLevel: number
combatPlayerScore: number
damageDealtToObjectives: number
damageDealtToTurrets: number
damageSelfMitigated: number
deaths: number
doubleKills: number
earlySurrenderAccomplice: boolean
firstBloodAssist: boolean
firstBloodKill: boolean
firstInhibitorAssist: boolean
firstInhibitorKill: boolean
firstTowerAssist: boolean
firstTowerKill: boolean
gameEndedInEarlySurrender: boolean
gameEndedInSurrender: boolean
goldEarned: number
goldSpent: number
inhibitorKills: number
item0: number
item1: number
item2: number
item3: number
item4: number
item5: number
item6: number
killingSprees: number
kills: number
largestCriticalStrike: number
largestKillingSpree: number
largestMultiKill: number
longestTimeSpentLiving: number
magicDamageDealt: number
magicDamageDealtToChampions: number
magicalDamageTaken: number
neutralMinionsKilled: number
neutralMinionsKilledEnemyJungle: number
neutralMinionsKilledTeamJungle: number
objectivePlayerScore: number
participantId: number
pentaKills: number
perk0: number
perk0Var1: number
perk0Var2: number
perk0Var3: number
perk1: number
perk1Var1: number
perk1Var2: number
perk1Var3: number
perk2: number
perk2Var1: number
perk2Var2: number
perk2Var3: number
perk3: number
perk3Var1: number
perk3Var2: number
perk3Var3: number
perk4: number
perk4Var1: number
perk4Var2: number
perk4Var3: number
perk5: number
perk5Var1: number
perk5Var2: number
perk5Var3: number
perkPrimaryStyle: number
perkSubStyle: number
physicalDamageDealt: number
physicalDamageDealtToChampions: number
physicalDamageTaken: number
playerScore0: number
playerScore1: number
playerScore2: number
playerScore3: number
playerScore4: number
playerScore5: number
playerScore6: number
playerScore7: number
playerScore8: number
playerScore9: number
quadraKills: number
sightWardsBoughtInGame: number
teamEarlySurrendered: boolean
timeCCingOthers: number
totalDamageDealt: number
totalDamageDealtToChampions: number
totalDamageTaken: number
totalHeal: number
totalMinionsKilled: number
totalPlayerScore: number
totalScoreRank: number
totalTimeCrowdControlDealt: number
totalUnitsHealed: number
tripleKills: number
trueDamageDealt: number
trueDamageDealtToChampions: number
trueDamageTaken: number
turretKills: number
unrealKills: number
visionScore: number
visionWardsBoughtInGame: number
wardsKilled: number
wardsPlaced: number
win: boolean
}
So i get this data in an array of objects, like this.
0: {assists: 0, causedEarlySurrender: false, champLevel: 18, combatPlayerScore: 0, damageDealtToObjectives: 60241, …}
1: {assists: 2, causedEarlySurrender: false, champLevel: 18, combatPlayerScore: 0, damageDealtToObjectives: 7592, …}
2: {assists: 0, causedEarlySurrender: false, champLevel: 16, combatPlayerScore: 0, damageDealtToObjectives: 8982, …}
I was trying a few things, but i can't find a way of doing this automatically, meaning not to have to type every key name.
This is what i have so far:
meanStats(){
let iterator = 0;
this.stats.forEach((m, i, array)=>{
iterator ++;
for (let [key, value] of Object.entries(m)) {
console.log(key, value);
switch (value) {
case Boolean:
if(key == "win"){
this.wins += value//if true should compute as 1 and if its not should be 0
}
if(key == "gameEndedInSurrender"){
this.surrenders += value
}
else{
break
}
break;
case Number://meanStat is the new object
this.meanStat.key += value
break;
default:
break;
}
}
});
}
The idea would be to access each keyname and value, check if its a boolean or a number,(lots of cases missing in case it's a boolean) sum that value on the correct key of the new object. After that divide all values by the iterator and i should have an average. Does not work, because key is not a known value of the object.
Any help would be appreciated. As allways thanks a lot.
Upvotes: 0
Views: 130
Reputation: 56
I'm posting the result, it might be usefull to some of you. I still need to handle booleans separately, so it's not 100% complete. Some of the values don't need to be averaged, others use a max value, so things got somewhat complex. I was able to use my object schema, so that's good.
Here's the code:
meanStats(){
this.stats.forEach((m, i, array)=>{
for (let [key, value] of Object.entries(m)) {
//setting everything to default
if(typeof(this.meanStat[key])=="undefined" && typeof(value)=="number"){
this.meanStat[key] = 0
}else if(typeof(this.meanStat[key])=="undefined" && typeof(value)=="boolean"){
this.meanStat[key] = false
//filtering by number types
}
if (typeof(value) == "number"){
let aux: number = this.meanStat[key]
if (key == "largestCriticalStrike" || key == "largestKillingSpree"||key == "largestMultiKill"){
if(value > this.meanStat[key]){
this.meanStat[key] = value
}
}else if (key == "doubleKills"|| key=="tripleKills"|| key == "quadraKills" || key=="pentakills"){
switch (key) {
//decided to make separate variables for this ones and also to have the average values.
case "doubleKills":
this.doublekills +=value
aux+=value
this.meanStat[key] = aux
break;
case "tripleKills":
this.triplekills +=value
aux+=value
this.meanStat[key] = aux
break;
case "quadraKills":
this.quadrakills +=value
aux+=value
this.meanStat[key] = aux
break;
case "pentakills":
this.pentakills +=value
aux+=value
this.meanStat[key] = aux
break;
default:
break;
}
}else{
aux+=value;
this.meanStat[key] = aux;
}
}else{
switch (key) {
//need to handle other booleans, have not done that yet that's why is only one case
case "win":
if(value == true){
this.wins ++
}
break;
default:
break;
}
}
}
});
//average every number except largestCriticalStrike
Object.keys(this.meanStat).forEach((key) => {
if (typeof(this.meanStat[key])== "number"){
if(key != "largestCriticalStrike" ){
this.meanStat[key] = this.meanStat[key]/this.stats.length
}
}
})
console.log(this.meanStat)
console.log(this.wins)
}
}
Code works, but if someone knows how to do this in a better way, feel free to post your own answer. Have a good day. Oh, and thx to @Arun Mohan for it's help.
Upvotes: 0
Reputation: 1227
You can try something like this. But you need to handle boolean separately.
const obj = {};
let a= [
{assists: 0, champLevel: 18, combatPlayerScore: 0, damageDealtToObjectives: 60241},
{assists: 2, champLevel: 18, combatPlayerScore: 0, damageDealtToObjectives: 60241},
{assists: 4, champLevel: 18, combatPlayerScore: 0, damageDealtToObjectives: 60241}
]
a.forEach( item => {
Object.keys(item).forEach(key => {
if (obj[key]) {
obj[key]+= item[key];
} else {
obj[key]= item[key];
}
});
});
Object.keys(obj).forEach((key) => obj[key] = obj[key]/a.length);
Upvotes: 1