1

I wrote a php script that will execute a full (dutch) soccer competition, based on parameters as Strength and moral.

After all rounds have been 'played', I use usort to define the end results.

These results are based on the 'Points' field. However, when two teams share the same number of points, further ranking has to be achieved by comparing the goal difference.

I tried to accomplish this sorting using first sorting om 'Points' and after that sorting om 'GoalDifference (GD)'. Unfortunately in the latter case goaldifference is sorted correctly but not the Points...

This is what the teams array looks like now:

    $teams = array
  (
    array(
        'Id' => 1,
        'Teamname' => 'Team 1,
        'Strength' => 22,
        'Moral' => 15,
        'Points' => 0,
        'Pro' => 0,
        'Contra'=> 0,
        'GD' => 0
    )    
}

Below the usort functions

    usort($teams, function($a, $b) {

    return $a['Points'] < $b['Points'];
});

    usort($teams, function($a, $b) {

    return $a['GD'] < $b['GD'];
});

So my question is, what is the best way to first sort on points and after that on goaldifference?

Kind regards,

Kees

Sougata Bose
  • 31,517
  • 8
  • 49
  • 87
kzpm
  • 133
  • 11

3 Answers3

1

Include both comparisons at the same time. So if the points are the same, use goal difference

usort($teams, function($a, $b) {
    return ($a['Points'] === $b['Points'] 
      ? $a['GD'] < $b['GD'] 
      : $a['Points'] < $b['Points']);
});
mike
  • 5,047
  • 2
  • 26
  • 32
  • 1
    You need to return a value <0, 0 or >0, not `true` or `false`. – deceze May 18 '15 at 08:13
  • You should, but since the author uses this same logic, maybe it has its own sorting mechanism based on `true`/`false` and not needing `-1`. Just wanted to be consistent with the question. – mike May 18 '15 at 08:16
  • 2
    If the OP is doing something wrong, then don't parrot it. Correct it. – deceze May 18 '15 at 08:17
1

You can build an more complex sort function where you check the columns in priority.

usort($teams, function($a, $b) {

    if ($a["Points"] < $b["Points"]) return -1;
    if ($a["Points"] > $b["Points"]) return 1;
    if ($a['GD'] < $b['GD']) return -1;
    if ($a['GD'] > $b['GD']) return 1;

    return 0;
});
take
  • 2,202
  • 2
  • 19
  • 36
1

You can use array_multisort() function.

$points = array();
$gd = array();
foreach ($teams as $key => $row) {
  $points[$key]  = $row['Points'];
  $gd[$key] = $row['GD'];
}

array_multisort($points, SORT_DESC, $gd, SORT_DESC, $teams);
Samir Das
  • 1,878
  • 12
  • 20