Created
July 21, 2018 10:32
-
-
Save alexFaunt/5250f498578e96e81a879c72a55ae664 to your computer and use it in GitHub Desktop.
Turn sweepstake teams + results into aggregate table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Results | |
const groupStages = [ | |
['Russia', 5, 0, 'Saudi Arabia'], | |
['Egypt', 0, 1, 'Uruguay'], | |
['Morocco', 0, 1, 'Iran'], | |
['Portugal', 3, 3, 'Spain'], | |
['France', 2, 1, 'Australia'], | |
['Argentina', 1, 1, 'Iceland'], | |
['Peru', 0, 1, 'Denmark'], | |
['Croatia', 2, 0, 'Nigeria'], | |
['Costa Rica', 0, 1, 'Serbia'], | |
['Germany', 0, 1, 'Mexico'], | |
['Brazil', 1, 1, 'Switzerland'], | |
['Sweden', 1, 0, 'Korea'], | |
['Belgium', 3, 0, 'Panama'], | |
['Tunisia', 1, 2, 'England'], | |
['Poland', 1, 2, 'Senegal'], | |
['Colombia', 1, 2, 'Japan'], | |
['Russia', 3, 1, 'Egypt'], | |
['Portugal', 1, 0, 'Morocco'], | |
['Uruguay', 1, 0, 'Saudi Arabia'], | |
['Iran', 0, 1, 'Spain'], | |
['France', 1, 0, 'Peru'], | |
['Denmark', 1, 1, 'Australia'], | |
['Argentina', 0, 3, 'Croatia'], | |
['Brazil', 2, 0, 'Costa Rica'], | |
['Nigeria', 2, 0, 'Iceland'], | |
['Serbia', 1, 2, 'Switzerland'], | |
['Belgium', 5, 2, 'Tunisia'], | |
['Mexico', 2, 1, 'Korea'], | |
['Germany', 2, 1, 'Sweden'], | |
['England', 6, 1, 'Panama'], | |
['Japan', 2, 2, 'Senegal'], | |
['Colombia', 3, 0, 'Poland'], | |
['Uruguay', 3, 0, 'Russia'], | |
['Saudi Arabia', 2, 1, 'Egypt'], | |
['Portugal', 1, 1, 'Iran'], | |
['Spain', 2, 2, 'Morocco'], | |
['France', 0, 0, 'Denmark'], | |
['Australia', 0, 2, 'Peru'], | |
['Croatia', 2, 1, 'Iceland'], | |
['Argentina', 2, 1, 'Nigeria'], | |
['Germany', 0, 2, 'Korea'], | |
['Mexico', 0, 3, 'Sweden'], | |
['Brazil', 2, 0, 'Serbia'], | |
['Switzerland', 2, 2, 'Costa Rica'], | |
['Poland', 1, 0, 'Japan'], | |
['Senegal', 0, 1, 'Colombia'], | |
['England', 0, 1, 'Belgium'], | |
['Tunisia', 2, 1, 'Panama'], | |
]; | |
const qualifiers = ['France', 'Argentina', 'Uruguay', 'Portugal', 'Spain', 'Russia', 'Croatia', 'Denmark', 'Brazil', 'Mexico', 'Belgium', 'Japan', 'Sweden', 'Switzerland', 'Colombia', 'England']; | |
const knockouts = [ | |
['France', 4, 3, 'Argentina'], | |
['Uruguay', 2, 1, 'Portugal'], | |
['Spain', 1, 1, 'Russia', 'Russia'], | |
['Croatia', 1, 1, 'Denmark', 'Croatia'], | |
['Brazil', 2, 0, 'Mexico'], | |
['Belgium', 3, 2, 'Japan'], | |
['Sweden', 1, 0, 'Switzerland'], | |
['England', 1, 1, 'Colombia', 'England'], | |
['France', 2, 0, 'Uruguay'], | |
['Belgium', 2, 1, 'Brazil'], | |
['England', 2, 0, 'Sweden'], | |
['Croatia', 2, 2, 'Russia', 'Croatia'], | |
['France', 1, 0, 'Belgium'], | |
['Croatia', 2, 1, 'England'], | |
['Belgium', 2, 0, 'England'], | |
['France', 4, 2, 'Croatia'] | |
] | |
// BORING CODE STUFF | |
const teamToPlayer = { | |
'Russia': 'Ben', | |
'Egypt': 'Ruth', | |
'Morocco': 'Louise', | |
'Portugal': 'Martin', | |
'France': 'Hester', | |
'Argentina': 'Charlotte', | |
'Peru': 'Rosie', | |
'Croatia': 'Alex', | |
'Costa Rica': 'Joe', | |
'Germany': 'Alex', | |
'Brazil': 'Charlotte', | |
'Sweden': 'Rosie', | |
'Belgium': 'Martin', | |
'Tunisia': 'Hester', | |
'Poland': 'James', | |
'Colombia': 'Charlotte', | |
'Saudi Arabia': 'Louise', | |
'Uruguay': 'James', | |
'Iran': 'Martin', | |
'Spain': 'Joe', | |
'Australia': 'Hannah', | |
'Iceland': 'Ben', | |
'Denmark': 'Hannah', | |
'Nigeria': 'James', | |
'Serbia': 'Hester', | |
'Mexico': 'Ruth', | |
'Switzerland': 'Alex', | |
'Korea': 'Joe', | |
'Panama': 'Ruth', | |
'England': 'Louise', | |
'Senegal': 'Hannah', | |
'Japan': 'Rosie', | |
} | |
const playerTeams = _.invertBy(teamToPlayer); | |
const players = Object.values(teamToPlayer).reduce(function (acc, player) { | |
acc[player] = { | |
GP: 0, | |
W: 0, | |
PW: 0, | |
D: 0, | |
L: 0, | |
GF: 0, | |
GA: 0, | |
GD: 0, | |
P: 0, | |
}; | |
return acc; | |
}, {}); | |
const reducer = function (acc, [team1, score1, score2, team2, winner]) { | |
const player1 = teamToPlayer[team1]; | |
const player2 = teamToPlayer[team2]; | |
const record1 = acc[player1]; | |
const record2 = acc[player2]; | |
record1.GP += 1; | |
record2.GP += 1; | |
record1.GF += score1; | |
record2.GF += score2; | |
record1.GA += score2; | |
record2.GA += score1; | |
record1.GD += (score1 - score2); | |
record2.GD += (score2 - score1); | |
if (score1 > score2) { | |
record1.W += 1; | |
record1.P += 3; | |
record2.L += 1; | |
} else if (score1 < score2) { | |
record2.W += 1; | |
record2.P += 3; | |
record1.L += 1; | |
} else { | |
record1.D += 1; | |
record1.P += 1; | |
record2.D += 1; | |
record2.P += 1; | |
if (winner) { | |
const winnerRecord = acc[teamToPlayer[winner]]; | |
// bonus point to winner | |
winnerRecord.P += 1; | |
winnerRecord.PW += 1; | |
} | |
} | |
return acc; | |
} | |
const groupTable = groupStages.reduce(reducer, players); | |
const table = knockouts.reduce(reducer, groupTable); | |
const remainers = knockouts.reduce((remains, [team1, score1, score2, team2, winner]) => { | |
if (score1 > score2) { | |
return _.without(remains, team2); | |
} else if (score1 < score2) { | |
return _.without(remains, team1); | |
} else if (winner && team1 === winner) { | |
return _.without(remains, team2); | |
} else if (winner && team2 === winner) { | |
return _.without(remains, team1); | |
} else { | |
throw new Error('no winner'); | |
} | |
}, qualifiers) | |
function Row ({ player, record }) { | |
const teams = playerTeams[player].map(function (team) { | |
return remainers.includes(team) ? <b>{team} </b> : <span>{team} </span>; | |
}); | |
return ( | |
<tr> | |
<td>{ player } ( { teams })</td> | |
<td>{ record.GP }</td> | |
<td>{ record.W }</td> | |
<td>{ record.PW }</td> | |
<td>{ record.D }</td> | |
<td>{ record.L }</td> | |
<td>{ record.GF }</td> | |
<td>{ record.GA }</td> | |
<td>{ record.GD }</td> | |
<td>{ record.P }</td> | |
<td>{ record.PCT.toFixed(2) }</td> | |
</tr> | |
); | |
} | |
function Table ({ table }) { | |
const orderedTable = Object.keys(table) | |
.map(function (player) { | |
const record = table[player]; | |
return { | |
player: player, | |
record: Object.assign({}, record, { | |
GFPG: (record.GF / record.GP), | |
GDPG: (record.GD / record.GP), | |
PCT: (record.P / (record.GP * 3)) * 100, | |
}), | |
}; | |
}) | |
.sort(function ({ record }, { record: recordB }) { | |
if (record.PCT < recordB.PCT) return 1; | |
if (record.PCT > recordB.PCT) return -1; | |
if (record.GDPG < recordB.GDPG) return 1; | |
if (record.GDPG > recordB.GDPG) return -1; | |
if (record.P > recordB.P) return 1; | |
if (record.P < recordB.P) return -1; | |
if (record.GFPG < recordB.GFPG) return 1; | |
if (record.GFPG > recordB.GFPG) return -1; | |
if (record.GF < recordB.GF) return 1; | |
if (record.GF > recordB.GF) return -1; | |
return 0; | |
}); | |
return ( | |
<table> | |
<thead> | |
<tr> | |
<th>Player</th> | |
<th>Played</th> | |
<th>Win</th> | |
<th>Penalty Win</th> | |
<th>Draw</th> | |
<th>Loss</th> | |
<th>GF</th> | |
<th>GA</th> | |
<th>GD</th> | |
<th>Points</th> | |
<th>Percentage</th> | |
</tr> | |
</thead> | |
<tbody> | |
{ | |
orderedTable.map(function ({ player, record }) { | |
return <Row key={player} player={player} record={record} /> | |
}) | |
} | |
</tbody> | |
</table> | |
); | |
}; | |
window.ReactDOM.render(<Table table={table} />, document.getElementById('app')) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment