2-мерная ассоциативная сортировка массивов с условными операторами в PHP - PullRequest
0 голосов
/ 29 сентября 2018

Мне сложно понять, как решить этот вопрос, это с бесплатного онлайн-тестового сайта.Вот ссылка: https://www.testdome.com/questions/php/league-table/19939?questionIds=7278,19939&generatorId=30&type=fromtest&testDifficulty=Hard

Но, чтобы быть более понятным, я пишу вопрос и мой ответ также.Начальный ответ есть в ссылке, написанной выше.

Вопрос:

Класс LeagueTable отслеживает счет каждого игрока в лиге.После каждой игры игрок записывает свой счет с помощью функции recordResult.

Ранг игрока в лиге рассчитывается по следующей логике:

Игрок с наибольшим количеством очков занимает первое место (ранг 1).Игрок с самым низким счетом занимает последнее место.Если два игрока связаны по количеству очков, то игрок, сыгравший меньше всего игр, получает более высокий рейтинг.Если два игрока связаны по количеству и количеству сыгранных игр, то игрок, который был первым в списке игроков, оценивается выше.Реализуйте функцию playerRank, которая возвращает игрока с данным рангом.

Например:

$table = new LeagueTable(array('Mike', 'Chris', 'Arnold'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 3);
$table->recordResult('Arnold', 5);
$table->recordResult('Chris', 5);
echo $table->playerRank(1);

Все игроки имеют одинаковое количество очков.Тем не менее, Арнольд и Крис сыграли меньше игр, чем Майк, и, поскольку Крис опередил Арнольда в списке игроков, он занял первое место.Поэтому приведенный выше код должен отображать «Крис».

Мой код:

<?php

class LeagueTable
{
    public function __construct($players)
    {
        $this->standings = array();
        foreach($players as $index => $p)
        {
            $this->standings[$p] = array
            (
                'index' => $index,
                'games_played' => 0, 
                'score' => 0
            );
        }
    }

    public function recordResult($player, $score)
    {
        $this->standings[$player]['games_played']++;
        $this->standings[$player]['score'] += $score;
    }

    public function playerRank($rank)
    {
        // I'm not sure what to do in here, not even sure where to place the conditional statements
        // but here's me trying to figure it out which I'm 90% sure I'm doing it wrong, 
        // since I'm using too many foreach function and arrays. Most probably not even close
        // to the correct answer.

        $comparison = $result = $this->standings;
        $player_names = array();

        foreach($this->standings as $name => $records)
        {
            foreach($comparison as $name_compare => $records_compare)
            {     
                if($this->standings[$name]['score'] > $comparison[$name_compare]['score'])
                {
                    $result[$name]['index'] = $this->standings[$name]['index'];
                }
                else if($this->standings[$name]['score'] == $comparison[$name_compare]['score']
                      && $this->standings[$name]['games_played'] < $comparison[$name_compare]['games_played'])
                {
                    $result[$name]['index'] = $this->standings[$name]['index'];
                }
                else if($this->standings[$name]['score'] == $comparison[$name_compare]['score']
                        && $this->standings[$name]['games_played'] == $comparison[$name_compare]['games_played'])
                {
                    $result[$name]['index'] = $this->standings[$name]['index'];
                }

                // This is where I'm confused, although there are conditional statemens there
                // but the code inside each "if" and "else if" is the same.

            }
        }

        foreach($result as $name => $records)
        {
            array_push($player_names,$name);
        }

        return $player_names[$rank-1]; //This should return "Chris" based on the record result, but it's not
    }
}

$table = new LeagueTable(array('Mike', 'Chris', 'Arnold'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 6);
$table->recordResult('Arnold', 5);
$table->recordResult('Chris', 5);
echo $table->playerRank(1);

Может кто-нибудь помочь мне решить этот вопрос, пожалуйста?

1 Ответ

0 голосов
/ 29 сентября 2018

Использование usort в вашем случае

usort($this->standings, function($a, $b) {
  // Compare scores
  $r = $b['score'] - $a['score'];
  // If two players are tied on score, 
  // then the player who has played the fewest games is ranked higher
  if(! $r) {
    $r = $a['games_played'] - $b['games_played'];
  }
  // If two players are tied on score and number of games played, 
  // then the player who was first in the list of players is ranked higher
  if(! $r) {
    $r = $a['index'] - $b['index'];
  }
  return $r;        
});

// You can watch result of sorting
print_r($this->standings);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...