title: Sorting 3 or more values with tiebreakers in PHP
body: <p>I'm ranking a list based on a set of tie-breaking criteria using <code>usort</code> in PHP. My problem is that the tiebreakers aren't applied correctly when there are 3 or more ties to break. The function only sorts between 2 entries as it iterates through the array.</p>
  
  <p>When 2 entries have identical <code>Overall wins</code>, the function checks <code>Division wins</code>; if those are identical, it checks <code>Head to head</code>; then <code>Points</code> if the tie still is not broken. This works great to break the tie between 2 entries, but with 3 or more ties, the iterative nature of this process is an issue.</p>
  
  <p>Example:</p>
  
  <p>3 entries have identical <code>Overall wins</code> and <code>Division wins</code>, so we check <code>Head to head</code> results.</p>
  
  <ul>
  <li>Team 1 beat Team 2.</li>
  <li>Team 2 beat Team 3.</li>
  <li>Team 3 beat Team 1.</li>
  </ul>
  
  <p>Therefore, we <em>should</em> move on to <code>Points</code> because the tie cannot be broken with <code>Head to head</code> as each team has one win over the other two teams. But my function doesn't ever make that third check, I guess because Team A and Team C aren't next to each other when <code>usort()</code> does it's thing...I'm not sure.</p>
  
  <p>Here is the comparison function I pass into <code>usort</code>:</p>
  
  <pre><code>function set_division_order($a, $b) {
  if ($a['wins'] == $b['wins'] &amp;&amp; $a['losses'] == $b['losses']) { //same overall record
      if ($a['div_wins'] == $b['div_wins'] &amp;&amp; $a['div_losses'] == $b['div_losses']) { //same division record
          $h2h = get_h2h_result($year, $a['team_id'], $b['team_id']);
          if ($h2h == 0) {    //same head-to-head record
              return ($b['pts'] - $a['pts']);
          }
          else {  //head-to-head winner
              return $h2h;
          }
      }
      else {  //different division record
          return ($b['div_wins'] - $a['div_wins']);
      }
  }
  else {  //different overall record
      return ($b['wins'] - $a['wins']);
  }
  }
  </code></pre>
  
  <p>The array getting passed into <code>usort($array, 'set_division_order')</code> which is causing problems:</p>
  
  <pre><code>Array
  (
      [0] =&gt; Array
          (
              [team_id] =&gt; 1
              [wins] =&gt; 3
              [losses] =&gt; 2
              [ties] =&gt; 0
              [div_wins] =&gt; 3
              [div_losses] =&gt; 2
              [div_ties] =&gt; 0
              [pts] =&gt; 513.9
          )
  
      [1] =&gt; Array
          (
              [team_id] =&gt; 2
              [wins] =&gt; 3
              [losses] =&gt; 2
              [ties] =&gt; 0
              [div_wins] =&gt; 3
              [div_losses] =&gt; 2
              [div_ties] =&gt; 0
              [pts] =&gt; 504.1
          )
  
      [2] =&gt; Array
          (
              [team_id] =&gt; 3
              [wins] =&gt; 3
              [losses] =&gt; 2
              [ties] =&gt; 0
              [div_wins] =&gt; 3
              [div_losses] =&gt; 2
              [div_ties] =&gt; 0
              [pts] =&gt; 517.7
          )
  
      [3] =&gt; Array
          (
              [team_id] =&gt; 4
              [wins] =&gt; 4
              [losses] =&gt; 1
              [ties] =&gt; 0
              [div_wins] =&gt; 4
              [div_losses] =&gt; 1
              [div_ties] =&gt; 0
              [pts] =&gt; 491.9
          )
  
      [4] =&gt; Array
          (
              [team_id] =&gt; 5
              [wins] =&gt; 2
              [losses] =&gt; 3
              [ties] =&gt; 0
              [div_wins] =&gt; 2
              [div_losses] =&gt; 3
              [div_ties] =&gt; 0
              [pts] =&gt; 393.3
          )
  
      [5] =&gt; Array
          (
              [team_id] =&gt; 6
              [wins] =&gt; 0
              [losses] =&gt; 5
              [ties] =&gt; 0
              [div_wins] =&gt; 0
              [div_losses] =&gt; 5
              [div_ties] =&gt; 0
              [pts] =&gt; 377.9
          )
  
  )
  </code></pre>
  
  <p>Sorry this was kind of long, but hopefully the problem is pretty evident. Now it's just time for a solution! I've scoured the PHP resources for the various sort functions, with no luck. I can't be the only one trying to break a 3-way tie with PHP. :)</p>
  
  <p>If I can get just the tied teams matching that criteria into a separate array, I could use a function to re-sort the original sorted array against the values of this new sub-array to order the tied teams within the main array.</p>
  
  <p>...And my head just exploded.</p>
  
  <p>Thanks!</p>