简体   繁体   English

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

[英]How to sum objects properties inside objects?

I am trying to sum the total of matches and participants of each cup in this object: 我想在这个对象中总计每个杯子的匹配和参与者的总数:

{
    "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
        }
    }
}

I don't know how to sum properties when the object has another object inside it (sorry I didn't learned that yet); 当对象里面有另一个对象时,我不知道如何对属性求和(对不起,我还没有学到);

I want to have a new object with the results of each cup total matches, and total participants. 我想要一个新的对象,每个杯子的总比赛结果和参赛者总数。 And also the total matches and participants of each category for all the cups except the cup_5 because it only have a single category. 还有除cup_5之外的所有杯子的每个类别的总匹配和参与者,因为它只有一个类别。

Something like: 就像是:

Cup_1 total matches: 72 Cup_1总比赛:72

Cup_1 total participants: 6740 Cup_1总参与人数:6740

Total Bronze matches (All cups): 57; 铜牌总数(所有杯子):57;

Total Bronze Participants (All cups): 5443 青铜参与者总数(所有杯子):5443

Example new object with the results: 示例新对象的结果:

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

I read that this sum of objects properties could be done with .map but I don't know how to properly use map with objects. 我读到这个对象属性的总和可以用.map完成,但我不知道如何正确使用map与对象。

If anyone could be kind to help me I would be grateful! 如果有人能帮助我,我将不胜感激!

Nested for loop will be helpful in fetching the matches and participants fields from cups var. 嵌套for循环将有助于从cups var中获取匹配和参与者字段。

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

Create an empty object for result.Then use forEach() to loop though all cups. 为result创建一个空对象。然后使用forEach()循环遍历所有cup。 And store result in the empty object. 并将结果存储在空对象中。

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

I would still separate the totals per cup from the totals per medal, and maybe add a grand total as well (since we are at it): 我仍然会将每杯的总数与每枚奖牌的总数分开,也可以加上一个总数(因为我们在这里):

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

You can use Object.keys , Object.values and destructuring for this - the below returns a summary of each cup: 您可以使用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); 

You can, of course, make a monolithic function that will do everything you need, but it's probably going to be easier to understand and maintain if you break it down into smaller ideas. 当然,你可以制作一个单一的功能,可以完成你需要的一切,但如果你把它分解成更小的想法,它可能会更容易理解和维护。

For example you can make a function that only takes an object and returns the sum of matches and participants . 例如,您可以创建一个仅接受对象并返回matchesparticipants总和的函数。 That will be short, readable and, most importantly, reusable: 这将是简短的,可读的,最重要的是,可重用:

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

Now you can use and reuse this function in a variety of ways. 现在,您可以通过各种方式使用和重用此功能。 For example to get all the main categories of the larger object, just reduce over the values and set a new key for each obj: 例如,要获取较大对象的所有主要类别,只需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)) 

As you should see this is very flexible and will let you create many different reports with the same core function. 正如您应该看到的,这非常灵活,可以让您使用相同的核心功能创建许多不同的报告。

I think below function should be generic solution to your problem. 我认为下面的功能应该是你的问题的通用解决方案。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM