简体   繁体   English

如何求和对象数组中 javascript 数组的属性之和?

[英]How can I sum the sum of a property of an javascript array in an array of objects?

I'm making a game where each player can submit an answer on a given question and other players can vote on an answer of another player.我正在制作一个游戏,每个玩家都可以提交对给定问题的答案,而其他玩家可以对另一个玩家的答案进行投票。 I store these results in an array of game rounds which may look something like the following:我将这些结果存储在一系列游戏轮次中,这些轮次可能类似于以下内容:

const roundHistory = [
  {
    question: 'question1',
    submissions: [
      {
        explanation: 'answer1',
        player: { id: 'id1', name: 'player1' },
        votes: [
          { id: 'id2', name: 'player2' },
          { id: 'id3', name: 'player3' },
        ],
      },
      {
        explanation: 'answer2',
        player: { id: 'id2', name: 'player2' },
        votes: [{ id: 'id1', name: 'player1' }],
      },
      {
        explanation: 'answer3',
        player: { id: 'id3', name: 'player3' },
        votes: [],
      },
    ],
  },
  {
    question: 'question2',
    submissions: [
      {
        explanation: 'answer1',
        player: { id: 'id1', name: 'player1' },
        votes: [
          { id: 'id2', name: 'player2' },
          { id: 'id3', name: 'player3' },
        ],
      },
      {
        explanation: 'answer2',
        player: { id: 'id2', name: 'player2' },
        votes: [{ id: 'id1', name: 'player1' }],
      },
      {
        explanation: 'answer3',
        player: { id: 'id3', name: 'player3' },
        votes: [],
      },
    ],
  },
];

As you can see there are 3 players in the game since each round (index of the roundHistory array) has 3 submissions.如您所见,游戏中有 3 名玩家,因为每一轮(roundHistory 数组的索引)都有 3 次提交。 Each submission has a property player which represents the player who submitted the submission.每个提交都有一个属性player ,代表提交提交的玩家。 And then each submission has a property votes which is an array of the players who voted for that submission.然后每个提交都有一个属性votes ,它是为该提交投票的玩家的数组。 Now my question:现在我的问题:

How can I get the total received votes per player of all rounds?我怎样才能得到每个玩家在所有回合中收到的总票数?


What I've tried so far... I thought, first I'd get the total received votes per player per round like so:到目前为止我尝试过的......我想,首先我会得到每个玩家每轮收到的总票数,如下所示:

 const roundHistory = [{question:'question1',submissions:[{explanation:'answer1',player:{id:'id1',name:'player1'},votes:[{id:'id2',name:'player2'},{id:'id3',name:'player3'},],},{explanation:'answer2',player:{id:'id2',name:'player2'},votes:[{id:'id1',name:'player1'}],},{explanation:'answer3',player:{id:'id3',name:'player3'},votes:[],},],},{question:'question2',submissions:[{explanation:'answer1',player:{id:'id1',name:'player1'},votes:[{id:'id2',name:'player2'},{id:'id3',name:'player3'},],},{explanation:'answer2',player:{id:'id2',name:'player2'},votes:[{id:'id1',name:'player1'}],},{explanation:'answer3',player:{id:'id3',name:'player3'},votes:[],},],},]; const getTotalReceivedVotesPerPlayerInRound = (round) => { return roundHistory[round].submissions.map((s) => ({ player: s.player, totalVotes: s.votes.length, })); } console.log(getTotalReceivedVotesPerPlayerInRound(0));

But I got stuck at adding all results of all rounds together.但是我坚持将所有回合的所有结果加在一起。 Note that I tried to simplify all used objects such as a player.请注意,我试图简化所有使用的对象,例如播放器。 In my application these are mostly classes for which I have several utility methods.在我的应用程序中,这些主要是我有几个实用方法的类。 One of them is the getTotalReceivedVotesPerPlayerInRound() method that I can use on a round (index of the roundHistory array).其中之一是我可以在回合中使用的getTotalReceivedVotesPerPlayerInRound()方法(roundHistory 数组的索引)。

I expect the final result to be of the same shape as the result of my already written function: An array of objects with two properties: player (the player object) and totalVotes .我希望最终结果与我已经编写的结果具有相同的形状 function:具有两个属性的对象数组: player (玩家对象)和totalVotes E. g.:例如:

const result = [
  {
    "player": {
      "id": "id1",
      "name": "player1"
    },
    "totalVotes": 2
  },
  {
    "player": {
      "id": "id2",
      "name": "player2"
    },
    "totalVotes": 1
  },
  {
    "player": {
      "id": "id3",
      "name": "player3"
    },
    "totalVotes": 0
  }
];

Presented below is one possible way to achieve the desired objective.下面介绍的是实现预期目标的一种可能方法。

Code Snippet代码片段

 const getPlayerTotalVotes = arr => ( Object.values( arr.reduce( (acc, { submissions}) => { submissions.forEach( ({ player: { id, name }, votes }) => { acc[id]??= { player: { id, name }, totalVotes: 0 }; acc[id].totalVotes += votes.length; } ) return acc; }, {} ) ) ); /* explanation of the code method to obtain the total votes per-player for all rounds const getPlayerTotalVotes = arr => ( Object.values( // extract only the values of the below intermediate result object arr.reduce( // ".reduce()" to iterate and sum votes-count (acc, { submissions}) => { // "acc" is the accumulator; destructure iterator // to directly access "submissions" array // then, iterate using ".forEach()" over "submissions" submissions.forEach( // destructure to access "votes" array and the particular player "id" ({ player: { id }, votes }) => { // conditionally-assign 0 if "id" not already present in "acc" acc[id]??= 0; // count the "votes" and add it to the "acc" prop with key as "id" acc[id] += votes.length; } ) return acc; // explicitly return "acc" for each iteration }, {} // "acc" is initialized as an empty object ) // implicit return of the result from ".reduce()" to caller ) ); */ const roundHistory = [{ question: 'question1', submissions: [{ explanation: 'answer1', player: { id: 'id1', name: 'player1' }, votes: [{ id: 'id2', name: 'player2' }, { id: 'id3', name: 'player3' }, ], }, { explanation: 'answer2', player: { id: 'id2', name: 'player2' }, votes: [{ id: 'id1', name: 'player1' }], }, { explanation: 'answer3', player: { id: 'id3', name: 'player3' }, votes: [], }, ], }, { question: 'question2', submissions: [{ explanation: 'answer1', player: { id: 'id1', name: 'player1' }, votes: [{ id: 'id2', name: 'player2' }, { id: 'id3', name: 'player3' }, ], }, { explanation: 'answer2', player: { id: 'id2', name: 'player2' }, votes: [{ id: 'id1', name: 'player1' }], }, { explanation: 'answer3', player: { id: 'id3', name: 'player3' }, votes: [], }, ], }, ]; console.log( 'total votes per player\n', getPlayerTotalVotes(roundHistory) );
 .as-console-wrapper { max-height: 100%;important: top: 0 }

Explanation解释

Inline comments added to the snippet above.添加到上面代码段的内联注释。

EDIT Using the given method to obtain sum of votes "per-round"编辑使用给定的方法获得“每轮”的票数总和

 const roundHistory = [{question:'question1',submissions:[{explanation:'answer1',player:{id:'id1',name:'player1'},votes:[{id:'id2',name:'player2'},{id:'id3',name:'player3'},],},{explanation:'answer2',player:{id:'id2',name:'player2'},votes:[{id:'id1',name:'player1'}],},{explanation:'answer3',player:{id:'id3',name:'player3'},votes:[],},],},{question:'question2',submissions:[{explanation:'answer1',player:{id:'id1',name:'player1'},votes:[{id:'id2',name:'player2'},{id:'id3',name:'player3'},],},{explanation:'answer2',player:{id:'id2',name:'player2'},votes:[{id:'id1',name:'player1'}],},{explanation:'answer3',player:{id:'id3',name:'player3'},votes:[],},],},]; const getTotalReceivedVotesPerPlayerInRound = (round) => { return roundHistory[round].submissions.map((s) => ({ player: s.player, totalVotes: s.votes.length, })); } const getTotalAllRounds = rh => ( Object.values( rh.reduce( (acc, _, idx) => { getTotalReceivedVotesPerPlayerInRound(idx)?.forEach( ({player: { id, name}, totalVotes}) => { acc[id]??= { player: {id, name}, totalVotes: 0 }; acc[id].totalVotes += totalVotes; } ); return acc; }, {} ) ) ); console.log(getTotalAllRounds(roundHistory));
 .as-console-wrapper { max-height: 100%;important: top: 0 }

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

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