Search code examples
javascriptangularjsarrayssortinghead

JS league table complex sort head 2 head


This, as far as i can search stack overflow answers, is not the 'normal' league table sorting issue.

I have a league table im working with in javascript (angular 2), which i can sort as needed by wins, games played etc like so:

standings.sort(function(a,b) {
 return b.won - a.won || a.played - b.played;
});

However my rules for sorting need to be more in depth to the tune of sorting by:

1) Most Wins

2) Least games played

3) Then if there are tied places, work out the head to head games won, then points diff in those head to head games:

  • 3 - a) sort on the head to head 'wins' only between any tied positions from points 1) & 2).
  • 3 - b) sort on the head to head 'points diff' only between the tied positions.

The complex part (for me at least!) is that i only need to compare the head to head wins and points difference to those on a shared position from points 1) and 2) and what those teams will be will only be known at the time of executing.

I cant figure out any sort of solution, let alone an elegant one! The below code obviously doesn't work, I've just made it up to try and help represent what i'm trying to achieve:

standings.sort(function(a,b) {
 return b.won - a.won || a.played - b.played || 
 a.head2heads[TIED_TEAM_KEY].wins - b.head2heads[TIED_TEAM_KEY].wins || 
 a.head2heads[TIED_TEAM_KEY].diff- b.head2heads[TIED_TEAM_KEY].diff;
});

I've got the head to head wins and points diff of each team against every other team on a property of each team in the standings (my league table) array. e.g. each standings object looks like:

{   "teamname": "name",
    "teamcode": "code",
    "won": "8",
    "lost": "10",
    "played": 18,
    "pointsScored": 1264,
    "pointsAgainst": 1345,
    "pointsDiff": -81,
    "head2": { "OPP_NAME_A": {}, "OPP_NAME_B": {}, ... }

So the data is on hand to pickout the individual head to head results. Just need the elegance to sort as per the criteria above. For now the standings array only has 16 teams (and this is unlikely to change ever). So even a slow verbose solution would be helpful!


Solution

  • So i figured this out in the end, sort function now looks like:

    standings.sort(function(a,b) {
     return b.won - a.won || a.played - b.played || 
     b.head2[a.teamname].home.head2wins - a.head2[b.teamname].home.head2wins || 
     b.head2[a.teamname].home.head2diff - a.head2[b.teamname].home.head2diff;
    });
    

    Guess it wasn't that complicated in and of itself, just confusing having so much data hiding under so many layers!