PHP 中带有条件语句的二维关联数组排序
2 dimensional associative array sorting with conditional statements in PHP
我不知道如何解决这个问题,它来自一个免费的在线测试网站。这是 link:https://www.testdome.com/questions/php/league-table/19939?questionIds=7278,19939&generatorId=30&type=fromtest&testDifficulty=Hard
但为了更清楚,我也写下了问题和答案。起始答案在上面写的 link 中。
问题:
The LeagueTable class tracks the score of each player in a league. After each game, the player records their score with the recordResult function.
The player's rank in the league is calculated using the following logic:
The player with the highest score is ranked first (rank 1). The player with the lowest score is ranked last.
If two players are tied on score, then the player who has played the fewest games is ranked higher.
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.
Implement the playerRank function that returns the player at the given rank.
For example:
$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);
All players have the same score. However, Arnold and Chris have played fewer games than Mike, and as Chris is before Arnold in the list of players, he is ranked first. Therefore, the code above should display "Chris".
我的代码:
<?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);
有人可以帮我解决这个问题吗?
在你的案例中使用 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);
您可以在下面找到完整的答案
<?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,
'rank' => $index
);
}
}
public function recordResult($player, $score)
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
function swap(&$x,&$y) {
$tmp=$x;
$x=$y;
$y=$tmp;
}
public function reRank()
{
//ranking all according to score
foreach($this->standings as $player => $records) {
foreach($this->standings as $player1 => $records1) {
if (($records['score'] > $records1['score']) && ($records['rank'] >= $records1['rank']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
// according to game played
if (($records['score'] == $records1['score']) && ($records['games_played'] > $records1['games_played']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
// according to index
if (($records['score'] == $records1['score']) && ($records['games_played'] == $records1['games_played'])&&
($records['index'] > $records1['index']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
}
}
}
public function playerRank($rank)
{
$this->reRank();
foreach($this->standings as $player => $records)
{
if ($records['rank']==$rank-1)
return $player;
}
}
}
$table = new LeagueTable(array('Chris', 'Mike', '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,
'name' => $p
);
}
}
public function recordResult($player, $score)
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
public function playerRank($rank)
{
$comparison = $result = $this->standings;
$player_names = array();
usort($this->standings, "comparatorFunc");
foreach($this->standings as $name => $records)
{
array_push($player_names,$records['name']);
}
// echo "hello<br>";
// print_r($player_names);
return $player_names[$rank-1];
}
}
function comparatorFunc($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;
}
$table = new LeagueTable(array('Mike', 'Chris', 'Arnold'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 6);
$table->recordResult('Arnold', 2);
$table->recordResult('Arnold', 3);
$table->recordResult('Chris', 5);
echo $table->playerRank(1);
<?php
class LeagueTable
{
public function __construct(array $players)
{
$this->standings = [];
foreach ($players as $index => $p) {
$this->standings[$p] = [
'index' => $index,
'games_played' => 0,
'score' => 0
];
}
}
public function recordResult(string $player, int $score): void
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
public function playerRank(int $rank): string
{
$result = '';
/**
* sort array
*/
uasort($this->standings, function ($player, $other_player) {
$r = $other_player['score'] - $player['score'];
if (!$r) {
$r = $player['games_played'] -
$other_player['games_played'];
}
if (!$r) {
$r = $player['index'] - $other_player['index'];
}
return $r;
});
if ($rank > count($this->standings)) {
$rank = count($this->standings);
}
$index = 1;
foreach ($this->standings as $player => $player_result) {
if ($index == $rank) {
$result = $player;
break;
} else {
$index++;
continue;
}
}
return $result;
}
}
$table = new LeagueTable(array('Mike', 'Chris', 'Arnold', 'Ali',
'Ahmad'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 3);
$table->recordResult('Arnold', 5);
$table->recordResult('Chris', 5);
$table->recordResult('Ali', 6);
$table->recordResult('Ahmad', 3);
$table->recordResult('Ahmad', 3);
echo $table->playerRank(1);
我不知道如何解决这个问题,它来自一个免费的在线测试网站。这是 link:https://www.testdome.com/questions/php/league-table/19939?questionIds=7278,19939&generatorId=30&type=fromtest&testDifficulty=Hard
但为了更清楚,我也写下了问题和答案。起始答案在上面写的 link 中。
问题:
The LeagueTable class tracks the score of each player in a league. After each game, the player records their score with the recordResult function.
The player's rank in the league is calculated using the following logic:
The player with the highest score is ranked first (rank 1). The player with the lowest score is ranked last. If two players are tied on score, then the player who has played the fewest games is ranked higher. 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. Implement the playerRank function that returns the player at the given rank.
For example:
$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);
All players have the same score. However, Arnold and Chris have played fewer games than Mike, and as Chris is before Arnold in the list of players, he is ranked first. Therefore, the code above should display "Chris".
我的代码:
<?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);
有人可以帮我解决这个问题吗?
在你的案例中使用 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);
您可以在下面找到完整的答案
<?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,
'rank' => $index
);
}
}
public function recordResult($player, $score)
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
function swap(&$x,&$y) {
$tmp=$x;
$x=$y;
$y=$tmp;
}
public function reRank()
{
//ranking all according to score
foreach($this->standings as $player => $records) {
foreach($this->standings as $player1 => $records1) {
if (($records['score'] > $records1['score']) && ($records['rank'] >= $records1['rank']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
// according to game played
if (($records['score'] == $records1['score']) && ($records['games_played'] > $records1['games_played']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
// according to index
if (($records['score'] == $records1['score']) && ($records['games_played'] == $records1['games_played'])&&
($records['index'] > $records1['index']))
{
$this->swap($this->standings[$player]['rank'],$this->standings[$player1]['rank']);
}
}
}
}
public function playerRank($rank)
{
$this->reRank();
foreach($this->standings as $player => $records)
{
if ($records['rank']==$rank-1)
return $player;
}
}
}
$table = new LeagueTable(array('Chris', 'Mike', '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,
'name' => $p
);
}
}
public function recordResult($player, $score)
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
public function playerRank($rank)
{
$comparison = $result = $this->standings;
$player_names = array();
usort($this->standings, "comparatorFunc");
foreach($this->standings as $name => $records)
{
array_push($player_names,$records['name']);
}
// echo "hello<br>";
// print_r($player_names);
return $player_names[$rank-1];
}
}
function comparatorFunc($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;
}
$table = new LeagueTable(array('Mike', 'Chris', 'Arnold'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 6);
$table->recordResult('Arnold', 2);
$table->recordResult('Arnold', 3);
$table->recordResult('Chris', 5);
echo $table->playerRank(1);
<?php
class LeagueTable
{
public function __construct(array $players)
{
$this->standings = [];
foreach ($players as $index => $p) {
$this->standings[$p] = [
'index' => $index,
'games_played' => 0,
'score' => 0
];
}
}
public function recordResult(string $player, int $score): void
{
$this->standings[$player]['games_played']++;
$this->standings[$player]['score'] += $score;
}
public function playerRank(int $rank): string
{
$result = '';
/**
* sort array
*/
uasort($this->standings, function ($player, $other_player) {
$r = $other_player['score'] - $player['score'];
if (!$r) {
$r = $player['games_played'] -
$other_player['games_played'];
}
if (!$r) {
$r = $player['index'] - $other_player['index'];
}
return $r;
});
if ($rank > count($this->standings)) {
$rank = count($this->standings);
}
$index = 1;
foreach ($this->standings as $player => $player_result) {
if ($index == $rank) {
$result = $player;
break;
} else {
$index++;
continue;
}
}
return $result;
}
}
$table = new LeagueTable(array('Mike', 'Chris', 'Arnold', 'Ali',
'Ahmad'));
$table->recordResult('Mike', 2);
$table->recordResult('Mike', 3);
$table->recordResult('Arnold', 5);
$table->recordResult('Chris', 5);
$table->recordResult('Ali', 6);
$table->recordResult('Ahmad', 3);
$table->recordResult('Ahmad', 3);
echo $table->playerRank(1);