从数组JavaScript中获取键值最大的对象



我有一个matchesScoreResult对象数组,如下所示:

[
{
roundId: '397a57f6-c9da-4017-bf98-62d7d48c1da5',
teamId: '32305c41-00e8-492a-859c-83c262230e06',
score: '7'
},
{
roundId: '397a57f6-c9da-4017-bf98-62d7d48c1da5',
teamId: '1122ef35-8bce-4310-838b-8221228cadc9',
score: '18'
},
{
roundId: 'c91f1a16-df97-4716-bb0d-8589612da704',
teamId: '32305c41-00e8-492a-859c-83c262230e06',
score: '21'
},
{
roundId: 'c91f1a16-df97-4716-bb0d-8589612da704',
teamId: '1122ef35-8bce-4310-838b-8221228cadc9',
score: '19'
}
]

这是game中某些rounds的数组(如您所见,roundId key被发现两次相同,因为有two teams that play in the same round,并且情况是same two teams播放two different rounds)

基于roundId和获胜的团队,我想增加firstTeamRoundsWon变量或secondTeamRoundsWon

首先我得到这样的unique round ids array:

let uniqueRoundIds = [...new Set(matchesScoreResult.map(item => item.roundId))]

基于uniqueRoundIds array,我做了如下操作:

uniqueRoundIds.map(roundId => matchesScoreResult.filter(teamRound => teamRound.roundId === roundId)
.map(round => round.reduce((previousValue, currentValue) => previousValue.score > currentValue.score ? firstTeamRoundsWon++ : secondTeamRoundsWon++))

我的问题是它增加了两倍的firstTeamRoundsWon,但根据我的数据,两个变量都应该是1

Is there something wrong that I did there?

我愿意考虑其他方法来解决这个问题。

谢谢你的帮助!

你可以用一些注释检查下面的逻辑

const matchesScoreResult = [{
roundId: '397a57f6-c9da-4017-bf98-62d7d48c1da5',
teamId: '32305c41-00e8-492a-859c-83c262230e06',
score: '7'
},
{
roundId: '397a57f6-c9da-4017-bf98-62d7d48c1da5',
teamId: '1122ef35-8bce-4310-838b-8221228cadc9',
score: '18'
},
{
roundId: 'c91f1a16-df97-4716-bb0d-8589612da704',
teamId: '32305c41-00e8-492a-859c-83c262230e06',
score: '21'
},
{
roundId: 'c91f1a16-df97-4716-bb0d-8589612da704',
teamId: '1122ef35-8bce-4310-838b-8221228cadc9',
score: '19'
}
]
//grouBy is not available in browsers yet, so we need to have polyfill for it
Array.prototype.groupBy = function(key) {
return this.reduce(function(current, value) {
(current[value[key]] = current[value[key]] || []).push(value);
return current;
}, {});
};
//group similar rounds to become matches
const matches = matchesScoreResult.groupBy('roundId')
//find all unquie team ids
let teams = [...new Set(matchesScoreResult.map(item => item.team))]
const teamScores = teams.reduce((teamData, team) => {
//loop through all matches with the first and second round data
for (const [firstRound, secondRound] of Object.values(matches)) {
//count for the team win the first round
if (Number(firstRound.score) > Number(secondRound.score)) {
if (!teamData[firstRound.teamId]) {
teamData[firstRound.teamId] = 0
}
teamData[firstRound.teamId] += 1
}

//count for the team win the second round
if (Number(firstRound.score) < Number(secondRound.score)) {
if (!teamData[secondRound.teamId]) {
teamData[secondRound.teamId] = 0
}
teamData[secondRound.teamId] += 1
}
}
return teamData
}, {})

//print out all team ids with the counts
console.log(teamScores)
//convert `teamScores` to your desired values
const [firstTeamRoundsWon, secondTeamRoundsWon] = Object.values(teamScores)
console.log({ firstTeamRoundsWon, secondTeamRoundsWon })

我相信你的问题是对reduce函数的误解。前一个值是它上次迭代所返回的值。在本例中,它将是firstTeamRoundsWon或secondTeamRoundsWon的值。还有一个数字。得分返回未定义。reduce函数用于以某种方式将一个数组缩减为单个值。

我不认为使用firstteamrounddswon和secondteamrounddswon是跟踪每次获胜次数的最佳方法,因为这似乎非常依赖于数组的顺序。

相反,我建议使用一个对象,键为teamID,值为他们获胜的次数。

const teamWins = {}
[...new Set(matchesScoreResult.map(round => round.teamId))].forEach(teamId => teamWins[teamId] = 0)
[...new Set(matchesScoreResult.map(round => round.roundId))].forEach(roundId => {
// Assuming there will only ever be 2 teams per round
const teams = matchesScoreResult.filter(round => round.roundId === roundId)
teamWins[teams[teams[0].score > teams[1].score ? 0 : 1].teamID]++
// If teams had a draw here then the second listed team in the array would have a win added.
})
console.log(teamWins)

顺便说一句。如果你想把数组改变成另一种形式,你应该使用map;如果你只想迭代每个结果,而不关心它是否返回一个值,你应该使用forEach。

最新更新