Search code examples
phparraysarray-filter

Filter usernames in an array based on the highest score


We have a online mini game on our platform where users with similar names, such as: Username, UserName and username face each other. All this works perfectly, but now we are adding a leaderboard that takes your data out of a PHP array.

$positions = ConfrontationGame::getResults()->toArray();

Then the $positions variable is an array that has the following structure:

$positions => array {

    [
        'username' => 'Exampleusername',
        'score' => '74'
    ],
    [
        'username' => 'ExampleUsername',
        'score' => '14'
    ],
    [
        'username' => 'exampleusername',  // WINNER
        'score' => '96'
    ]

}

We use this array to create a table of positions where users with similar usernames (EmapleUsername,Exampleusername and exampleusername) who faced each other should only leave the one with the highest score, in this case the winner exampleusername

This is what we have:

$results_table = array_filter($positions, function($val, $key) {

        if($key === 'username' && in_array(strtolower($val), $positions)) {
            if($key === 'score') {
                // ...
                // What is done here?
            }        
        }

    }, ARRAY_FILTER_USE_BOTH);

Solution

  • Here's one way of looking at it.

    <?php
    
    $playersWithPosition = [[
        'username' => 'Exampleusername',
        'score' => '74'
    ],[
        'username' => 'ExampleUsername',
        'score' => '14'
    ],[
        'username' => 'exampleusername',  // WINNER
        'score' => '96'
    ]];
    
    $leaderboard = static function(array $players) {
        $leaders = [];
    
        foreach($players as $player) {
            $leaders[(int) $player['score']] = $player['username'];
        }
    
        ksort($leaders);
    
        // Higher score is better, so reverse order.
        return array_values(array_reverse($leaders));
    };
    
    $leading = static function(array $players) use(&$leaderboard): ?string {
        return $leaderboard($players)[0] ?? null;
    };
    
    var_dump($leaderboard($playersWithPosition), $leading($playersWithPosition));
    

    Which gives:

    array(3) {
      [0]=>
      string(15) "exampleusername"
      [1]=>
      string(15) "Exampleusername"
      [2]=>
      string(15) "ExampleUsername"
    }
    
    string(15) "exampleusername"
    

    https://3v4l.org/ICGZf