如何对对象内的对象属性求和?

问题描述 投票:2回答:6

我想在这个对象中总计每个杯子的匹配和参与者的总数:

{
    "Cup_1": {
        "bronze": {
            "matches": 3,
            "participants": 289
        },
        "silver": {
            "matches": 20,
            "participants": 1874
        },
        "gold": {
            "matches": 35,
            "participants": 3227
        },
        "platinum": {
            "matches": 3,
            "participants": 294
        },
        "diamond": {
            "matches": 5,
            "participants": 482
        },
        "ace": {
            "matches": 6,
            "participants": 574
        }
    },
    "Cup_2": {
        "bronze": {
            "matches": 17,
            "participants": 1609
        },
        "silver": {
            "matches": 46,
            "participants": 4408
        },
        "gold": {
            "matches": 157,
            "participants": 14391
        },
        "platinum": {
            "matches": 0,
            "participants": 0
        },
        "diamond": {
            "matches": 5,
            "participants": 469
        },
        "ace": {
            "matches": 10,
            "participants": 959
        }
    },
    "Cup_3": {
        "bronze": {
            "matches": 35,
            "participants": 3358
        },
        "silver": {
            "matches": 96,
            "participants": 9069
        },
        "gold": {
            "matches": 313,
            "participants": 29527
        },
        "platinum": {
            "matches": 10,
            "participants": 960
        },
        "diamond": {
            "matches": 16,
            "participants": 1538
        },
        "ace": {
            "matches": 45,
            "participants": 4280
        }
    },
    "Cup_4": {
        "bronze": {
            "matches": 2,
            "participants": 187
        },
        "silver": {
            "matches": 8,
            "participants": 742
        },
        "gold": {
            "matches": 37,
            "participants": 3416
        },
        "platinum": {
            "matches": 0,
            "participants": 0
        },
        "diamond": {
            "matches": 2,
            "participants": 196
        },
        "ace": {
            "matches": 3,
            "participants": 290
        }
    },
    "Cup_5": {
        "bronze": {
            "matches": 89,
            "participants": 1638
        }
    }
}

当对象里面有另一个对象时,我不知道如何对属性求和(对不起,我还没有学到);

我想要一个新的对象,每个杯子的总比赛结果和参赛者总数。还有除cup_5之外的所有杯子的每个类别的总匹配和参与者,因为它只有一个类别。

就像是:

Cup_1总比赛:72

Cup_1总参与人数:6740

铜牌总数(所有杯子):57;

青铜参与者总数(所有杯子):5443

示例新对象的结果:

var cups_result = {
  "Total_Cup_1": {
    matches: 72,
    participants: 6740,
  },
  "Total_Bronze": {
    matches: 57,
    participants: 5443,
  },
}

我读到这个对象属性的总和可以用.map完成,但我不知道如何正确使用map与对象。

如果有人能帮助我,我将不胜感激!

javascript string function object ecmascript-6
6个回答
2
投票

我仍然会将每杯的总数与每枚奖牌的总数分开,也可以加上一个总数(因为我们在这里):

const data = {"Cup_1": {"bronze": {"matches": 3,"participants": 289},"silver": {"matches": 20,"participants": 1874},"gold": {"matches": 35,"participants": 3227},"platinum": {"matches": 3,"participants": 294},"diamond": {"matches": 5,"participants": 482},"ace": {"matches": 6,"participants": 574}},"Cup_2": {"bronze": {"matches": 17,"participants": 1609},"silver": {"matches": 46,"participants": 4408},"gold": {"matches": 157,"participants": 14391},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 5,"participants": 469},"ace": {"matches": 10,"participants": 959}},"Cup_3": {"bronze": {"matches": 35,"participants": 3358},"silver": {"matches": 96,"participants": 9069},"gold": {"matches": 313,"participants": 29527},"platinum": {"matches": 10,"participants": 960},"diamond": {"matches": 16,"participants": 1538},"ace": {"matches": 45,"participants": 4280}},"Cup_4": {"bronze": {"matches": 2,"participants": 187},"silver": {"matches": 8,"participants": 742},"gold": {"matches": 37,"participants": 3416},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 2,"participants": 196},"ace": {"matches": 3,"participants": 290}},"Cup_5": {"bronze": {"matches": 89,"participants": 1638}}}

const cupTotals = {}, 
      medalTotals = {}, 
      grandTotal = { matches: 0, participants: 0 };
for (const cup in data) {
    cupTotals[cup] = { matches: 0, participants: 0 };
    for (let medal in data[cup]) {
        const {matches, participants} = data[cup][medal];
        if (cup === "Cup_5" && medal === "bronze") medal = "junior";
        cupTotals[cup].matches += matches;
        cupTotals[cup].participants += participants;
        if (!medalTotals[medal]) medalTotals[medal] = { matches: 0, participants: 0 };
        medalTotals[medal].matches += matches;
        medalTotals[medal].participants += participants;
        grandTotal.matches += matches;
        grandTotal.participants += participants;
    }
}
const results = { cupTotals, medalTotals, grandTotal };

console.log(results);

2
投票

嵌套for循环将有助于从cups var中获取匹配和参与者字段。

for (var c in cups) { 
   for ( let medal in cups[c] ) { 
        console.log(cups[c][medal]["matches"], cups[c][medal]["participants"]);
   } 
} 

2
投票

您可以使用Object.keysObject.values和destructuring - 下面返回每个杯子的摘要:

const cup_data = {
  "Cup_1": {
    "bronze": {
      "matches": 3,
      "participants": 289
    },
    "silver": {
      "matches": 20,
      "participants": 1874
    },
    "gold": {
      "matches": 35,
      "participants": 3227
    },
    "platinum": {
      "matches": 3,
      "participants": 294
    },
    "diamond": {
      "matches": 5,
      "participants": 482
    },
    "ace": {
      "matches": 6,
      "participants": 574
    }
  },
  "Cup_2": {
    "bronze": {
      "matches": 17,
      "participants": 1609
    },
    "silver": {
      "matches": 46,
      "participants": 4408
    },
    "gold": {
      "matches": 157,
      "participants": 14391
    },
    "platinum": {
      "matches": 0,
      "participants": 0
    },
    "diamond": {
      "matches": 5,
      "participants": 469
    },
    "ace": {
      "matches": 10,
      "participants": 959
    }
  },
  "Cup_3": {
    "bronze": {
      "matches": 35,
      "participants": 3358
    },
    "silver": {
      "matches": 96,
      "participants": 9069
    },
    "gold": {
      "matches": 313,
      "participants": 29527
    },
    "platinum": {
      "matches": 10,
      "participants": 960
    },
    "diamond": {
      "matches": 16,
      "participants": 1538
    },
    "ace": {
      "matches": 45,
      "participants": 4280
    }
  },
  "Cup_4": {
    "bronze": {
      "matches": 2,
      "participants": 187
    },
    "silver": {
      "matches": 8,
      "participants": 742
    },
    "gold": {
      "matches": 37,
      "participants": 3416
    },
    "platinum": {
      "matches": 0,
      "participants": 0
    },
    "diamond": {
      "matches": 2,
      "participants": 196
    },
    "ace": {
      "matches": 3,
      "participants": 290
    }
  },
  "Cup_5": {
    "bronze": {
      "matches": 89,
      "participants": 1638
    }
  }
};

let cup_results = {};
Object.keys(cup_data).forEach(key => {
  let newCupKey = "Total_" + key;
  cup_results[newCupKey] = {};
  cup_results[newCupKey].matches = Object.values(cup_data[key]).reduce((acc, {
    matches
  }) => acc + matches, 0);
  cup_results[newCupKey].participants = Object.values(cup_data[key]).reduce((acc, {
    participants
  }) => acc + participants, 0);
});

console.log(cup_results);

2
投票

为结果创建一个空对象。然后使用forEach()循环遍历所有杯子。并将结果存储在空对象中。

let data = {
    "Cup_1": {
        "bronze": {
            "matches": 3,
            "participants": 289
        },
        "silver": {
            "matches": 20,
            "participants": 1874
        },
        "gold": {
            "matches": 35,
            "participants": 3227
        },
        "platinum": {
            "matches": 3,
            "participants": 294
        },
        "diamond": {
            "matches": 5,
            "participants": 482
        },
        "ace": {
            "matches": 6,
            "participants": 574
        }
    },
    "Cup_2": {
        "bronze": {
            "matches": 17,
            "participants": 1609
        },
        "silver": {
            "matches": 46,
            "participants": 4408
        },
        "gold": {
            "matches": 157,
            "participants": 14391
        },
        "platinum": {
            "matches": 0,
            "participants": 0
        },
        "diamond": {
            "matches": 5,
            "participants": 469
        },
        "ace": {
            "matches": 10,
            "participants": 959
        }
    },
    "Cup_3": {
        "bronze": {
            "matches": 35,
            "participants": 3358
        },
        "silver": {
            "matches": 96,
            "participants": 9069
        },
        "gold": {
            "matches": 313,
            "participants": 29527
        },
        "platinum": {
            "matches": 10,
            "participants": 960
        },
        "diamond": {
            "matches": 16,
            "participants": 1538
        },
        "ace": {
            "matches": 45,
            "participants": 4280
        }
    },
    "Cup_4": {
        "bronze": {
            "matches": 2,
            "participants": 187
        },
        "silver": {
            "matches": 8,
            "participants": 742
        },
        "gold": {
            "matches": 37,
            "participants": 3416
        },
        "platinum": {
            "matches": 0,
            "participants": 0
        },
        "diamond": {
            "matches": 2,
            "participants": 196
        },
        "ace": {
            "matches": 3,
            "participants": 290
        }
    },
    "Cup_5": {
        "bronze": {
            "matches": 89,
            "participants": 1638
        }
    }
}



function sumOfCup(obj,cupNos,cuptypes){
  let result = {};
  Object.keys(obj).forEach(a => {
    Object.keys(obj[a]).forEach(x => {
    if(result[`Total_${x}`]){
      result[`Total_${x}`].matches += obj[a][x].matches;
      result[`Total_${x}`].participants += obj[a][x].participants;
    }
    else result[`Total_${x}`] = {...obj[a][x]};
  })
  result[`Total_${a}`] = Object.values(obj[a]).reduce((ac,a)=>{
    ac.matches += a.matches 
    ac.participants += a.participants;
    return ac;
  },{matches:0,participants:0})
  })

  
 
  return result
  
  
  
}
console.log(data);
console.log(sumOfCup(data))

2
投票

当然,你可以制作一个单一的功能,可以完成你需要的一切,但如果你把它分解成更小的想法,它可能会更容易理解和维护。

例如,您可以创建一个只接受一个对象并返回matchesparticipants之和的函数。这将是简短的,可读的,最重要的是,可重用:

function sumObj(obj){
  // returns the sum of matches and participant propertes of all obj's values
  return Object.values(obj).reduce((sums, o) => {
    sums.matches += o.matches
    sums.participants += o.participants
    return sums
  }, {matches: 0, participants: 0})
}

现在,您可以通过各种方式使用和重用此功能。例如,要获取较大对象的所有主要类别,只需对值进行reduce,并为每个obj设置一个新键:

let o = {"Cup_1": {"bronze": {"matches": 3,"participants": 289},"silver": {"matches": 20,"participants": 1874},"gold": {"matches": 35,"participants": 3227},"platinum": {"matches": 3,"participants": 294},"diamond": {"matches": 5,"participants": 482},"ace": {"matches": 6,"participants": 574}},"Cup_2": {"bronze": {"matches": 17,"participants": 1609},"silver": {"matches": 46,"participants": 4408},"gold": {"matches": 157,"participants": 14391},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 5,"participants": 469},"ace": {"matches": 10,"participants": 959}},"Cup_3": {"bronze": {"matches": 35,"participants": 3358},"silver": {"matches": 96,"participants": 9069},"gold": {"matches": 313,"participants": 29527},"platinum": {"matches": 10,"participants": 960},"diamond": {"matches": 16,"participants": 1538},"ace": {"matches": 45,"participants": 4280}},"Cup_4": {"bronze": {"matches": 2,"participants": 187},"silver": {"matches": 8,"participants": 742},"gold": {"matches": 37,"participants": 3416},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 2,"participants": 196},"ace": {"matches": 3,"participants": 290}},"Cup_5": {"bronze": {"matches": 89,"participants": 1638}}}

/* 
 * Base function. Sum an object's matches & participants
 */
function sumObj(obj){
  return Object.values(obj).reduce((sums, o) => {
    sums.matches += o.matches
    sums.participants += o.participants
    return sums
  }, {matches: 0, participants: 0})
}

let sums = Object.entries(o).reduce((totals, [key, val]) => {
  totals[key] = sumObj(val) // call the sum function for each value
  return totals
}, {})
console.log(sums)

/* 
 * Pass sums back into the same function to get a grand total: 
 */
console.log("grand total: ", sumObj(sums))

/* 
 * To sum only a subset filter the obj entries first:
 * Without Cup_5 
 */
let minus_5 = Object.entries(o)
  .filter(([k, v ]) => k != 'Cup_5')  // filter first
  .reduce((totals, [key, val]) => {
      totals[key] = sumObj(val)       // call the sum function for each value
      return totals
}, {})
console.log("all but Cup_5", minus_5)

/* 
 * To get only a subcategory, use map and make a new
 * array and pass it to the function:
 * Only bronze:
 */ 
let bronze = Object.values(o).map(item => item.bronze)  // get only bronze
console.log("Bronze", sumObj(bronze))

正如您应该看到的,这非常灵活,可以让您使用相同的核心功能创建许多不同的报告。


1
投票

我认为下面的功能应该是你的问题的通用解决方案。

const data = {"Cup_1": {"bronze": {"matches": 3,"participants": 289},"silver": {"matches": 20,"participants": 1874},"gold": {"matches": 35,"participants": 3227},"platinum": {"matches": 3,"participants": 294},"diamond": {"matches": 5,"participants": 482},"ace": {"matches": 6,"participants": 574}},"Cup_2": {"bronze": {"matches": 17,"participants": 1609},"silver": {"matches": 46,"participants": 4408},"gold": {"matches": 157,"participants": 14391},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 5,"participants": 469},"ace": {"matches": 10,"participants": 959}},"Cup_3": {"bronze": {"matches": 35,"participants": 3358},"silver": {"matches": 96,"participants": 9069},"gold": {"matches": 313,"participants": 29527},"platinum": {"matches": 10,"participants": 960},"diamond": {"matches": 16,"participants": 1538},"ace": {"matches": 45,"participants": 4280}},"Cup_4": {"bronze": {"matches": 2,"participants": 187},"silver": {"matches": 8,"participants": 742},"gold": {"matches": 37,"participants": 3416},"platinum": {"matches": 0,"participants": 0},"diamond": {"matches": 2,"participants": 196},"ace": {"matches": 3,"participants": 290}},"Cup_5": {"bronze": {"matches": 89,"participants": 1638}}};

function getCumlativeData(data) {
  return Object.keys(data).reduce((cumData, cup)=>{
    let cupCumlative = {matches: 0, participants:0};
     Object.keys(data[cup]).forEach(med => {
       cumData[`Total_${med}`] = cumData[`Total_${med}`] || {matches: 0, participants:0};
       cumData[`Total_${med}`] = {
         matches: cumData[`Total_${med}`].matches + data[cup][med].matches,
         participants: cumData[`Total_${med}`].participants + data[cup][med].participants,
       };
       cupCumlative = {
          matches: cupCumlative.matches +  data[cup][med].matches,
          participants: cupCumlative.participants +  data[cup][med].participants
       };
     });
     return {...cumData, [`Total_${cup}`]: cupCumlative};
  },{});
}

console.log(getCumlativeData(data));
© www.soinside.com 2019 - 2024. All rights reserved.