Mcg1978
Mcg1978

Reputation: 464

Comparing multiple arrays

I'm trying to figure out how to write a tie-breaker function. The following records are all tied for one reason or another, so to break the tie, we sort each result and then go through each line. The tie is broken at the first point there is a difference.

In the example below on the first pass $result[c] is eliminated, but a and b are still tied. Then on the second pass a is eliminated because it is greater than b. So the result is b, a, c

$result[a] = array(1, 3, 4, 5);
$result[b] = array(1, 2, 3, 7);
$result[c] = array(2, 3, 3, 5);

And to make it even more complicated, I won't always have the same number of results to compare. It could be anything more than 2.

I really hope this makes sense.

Upvotes: 5

Views: 3844

Answers (3)

nickb
nickb

Reputation: 59699

Here is a working solution. Let me know if you need a better explanation of how it works. I've left the debugging statements in so you should be able to discern what it is doing. This solution will work with an arbitrary number of competitors, as long as they each have the same $num_elements in each array.

$result = array();
$result['a'] = array(1, 3, 4, 5);
$result['b'] = array(1, 2, 3, 7);
$result['c'] = array(2, 3, 3, 5);

$num_elements = 4; // In each array
$num_competitors = count( $result);

$finish_order = array();
$keys = $winners = array_keys( $result);

// $i is the current index into each competitor's array
// $j is the current index into the $keys array (telling us the current competitor)
// $k is the next index into the $keys array (telling us the next competitor, i.e. the competitor to compare the current competitor with)
for( $i = 0; $i < $num_elements; $i++) {

    // If we've eliminated all but one winner, we're done!
    if( count( $winners) == 1) { 
        $finish_order[] = array_pop( $winners);
        break;
    }

    echo 'Element number ' . $i . "\n";

    for( $j = 0; $j < $num_competitors; $j++) {

        // If we've already eliminated this competitor, continue;
        if( !isset( $winners[$j])) continue;

        for( $k = $j + 1; $k < $num_competitors; $k++) {

            // If we've already eliminated this competitor, continue;
            if( !isset( $winners[$k])) continue;

            echo "\t - Who wins: " . $result[ $keys[$j] ][$i] . ' from ' . $keys[$j] . ' or ' . $result[ $keys[$k] ][$i] . ' from ' . $keys[$k] . "?\n";

            if( $result[ $keys[$j] ][$i] < $result[ $keys[$k] ][$i]) {

                echo "\t\t *** " . $keys[$k] . ' is out!' . "\n";
                $finish_order[] = $keys[$k];                
                unset( $winners[$k]);
            }

            if( $result[ $keys[$j] ][$i] > $result[ $keys[$k] ][$i]) {

                echo "\t\t *** " . $keys[$j] . ' is out!' . "\n";
                $finish_order[] = $keys[$j];                
                unset( $winners[$j]);
            }

        }
    }
}

echo "Game over - Result order is: " . implode( ', ', array_reverse( $finish_order));

Output:

Element number 0
     - Who wins: 1 from a or 1 from b?
     - Who wins: 1 from a or 2 from c?
         *** c is out!
Element number 1
     - Who wins: 3 from a or 2 from b?
         *** a is out!
Game over - Result order is: b, a, c

Demo

Upvotes: 0

goat
goat

Reputation: 31813

In php, you can actually compare arrays directly using relation operators

if ($result['a'] > $result['b']) {

}

php will just loop through the sub arrays, comparing their elements. There's more detail if you want to read http://php.net/manual/en/language.operators.comparison.php

Anyway, you can take advantage of this and just sort it.

asort($result);
print_r($result);

If you need a way to get the n'th place entry, do

asort($result);
print_r($result);
$ranked = array_keys($result);
$secondPlace = $ranked[1]; // a
print_r($result[$secondPlace]);

and if you need the rank indice of a letter

$letterRanks = array_flip($ranked);
echo $letterRanks['a']; // 1, for second 

Upvotes: 3

bobwienholt
bobwienholt

Reputation: 17610

$i = 0;
while (count($result) > 1) {
   $winners = array();
   $best = PHP_INT_MAX;
   foreach ($result as $x) {
      if ($x[$i] == $best) {
         $winners[] = $x;
      } else if ($x[$i] < $best) {
         $winners = array($x);
         $best = $x[$i];
      }
   }
   $i++;
   $result = $winners;
}

This is just a quick and dirty piece of code... it doesn't handle the situation where the arrays are different sizes. Mostly because I'm not sure which of array(1,2,3) or array(1,2) should "win". Also, it doesn't do any array bounds checking or handle the situation where more than one array is tied after all elements have been compared.

Upvotes: 0

Related Questions