如何比较从结尾到开始的5个数值阵列?

时间:2015-08-19 09:23:11

标签: php arrays sorting

我正在制作一张discgolf记分卡,并且卡在了发球区域。 我有5个不同的阵列,我需要根据之前其他洞的分数来确定谁将首先在下一个洞中投掷。如果人们得分相同,我需要在此之前检查分数,依此类推。得分最低。

示例:

$player1score = array(3,3,3,3,4,3);
$player2score = array(3,3,3,3,3,4);
$player3score = array(3,3,3,3,2,3);
$player4score = array(3,3,3,3,3,3);
$player5score = array(3,3,3,2,2,3);

数组中的每个条目代表前一个洞的得分。 如果玩家的分数与其他人相同,则在此之前查看分数以确定顺序。

以上输出需要类似于:

  • 1st:Player 5
  • 2nd:Player 3
  • 3rd:Player 4
  • 4th:Player 1
  • 5th:Player 2

修改

由于起始位置与球员的编号相同,如果他们具有完全相同的得分,则应首先列出编号最小的球员。但是阵列中的最新分数应该是位置的第一个分数,而不是阵列的整个总和。

如果数组是:

$player1score = array(3,3,3,3,4,3);
$player2score = array(3,3,3,3,3,2);
$player3score = array(3,3,3,3,2,3);
$player4score = array(3,3,3,3,3,3);
$player5score = array(3,3,3,2,2,3);

输出结果为:

  • 1st:Player 2
  • 2nd:Player 5
  • 3rd:Player 3
  • 4th:Player 4
  • 5th:Player 1

2 个答案:

答案 0 :(得分:0)

这应该适合你:

首先将所有玩家分数放入一个数组$players。然后浏览每个球员的得分并使用该键确定每个得分及其位置的权重。

在此之后,只需将每位玩家的所有分数与array_map()以及array_sum()结合起来作为回调。

现在你可以对阵列ASC进行排序,并保持关键码仍然记住哪个牌手在排名中占据哪个位置,所以为此使用asort()

最后只显示结果。

<?php

    $player1score = array(3,3,3,3,4,3);
    $player2score = array(3,3,3,3,3,4);
    $player3score = array(3,3,3,3,2,3);
    $player4score = array(3,3,3,3,3,3);
    $player5score = array(3,3,3,2,2,3);

    $players = [
        $player1score,
        $player2score,
        $player3score,
        $player4score,
        $player5score,
    ];

    foreach($players as $outerKey => $player) {

        foreach($player as $key => $score)
            $players[$outerKey][$key] = ($key + 1) * $score;

    }

    $players = array_map("array_sum", $players);
    asort($players);

    $counter = 1;
    foreach($players as $key => $playerScore) {
        echo "$counter. player: " . ($key + 1) . "<br>";
        $counter++;
    }

?>

输出:

1. player: 5
2. player: 3
3. player: 4
4. player: 1
5. player: 2

修改

所以我稍微更改了我的代码,现在它的工作原理如下:

首先,我创建了一个多维数组,其中我为每个玩家存储了以下数据:

  • scores(每个单一分数)
  • totalScore(根据他们的位置总分加上他们的权重)
  • position(排名位置)
  • player(玩家编号)

声明该数组后,我遍历每个玩家并计算总得分(totalScore)。然后,我使用array_column()提取totalScore列,并使用asort()对其进行ASC排序,以保留播放器密钥。

现在我可以遍历已排序的数组($totalScoresSorted)并使用该键为$players中的每个玩家分配正确的位置。

之后,我可以使用uasort()$players排序整个position数组,以应用我自己的比较功能并保留播放器键。

最后只需显示数据。

<?php

    $player1score = array(3,3,3,3,4,3);
    $player2score = array(3,3,3,3,3,4);
    $player3score = array(3,3,3,3,2,3);
    $player4score = array(3,3,3,3,3,3);
    $player5score = array(3,3,3,2,2,3);

    $players = [
        [
            "scores" => array_values($player1score),
            "totalScore" => 0,
            "position" => 0,
            "playerNumber" => 1,
        ],
        [
            "scores" => array_values($player2score),
            "totalScore" => 0,
            "position" => 0,
            "playerNumber" => 2,
        ],
        [
            "scores" => array_values($player3score),
            "totalScore" => 0,
            "position" => 0,
            "playerNumber" => 3,
        ],
        [
            "scores" => array_values($player4score),
            "totalScore" => 0,
            "position" => 0,
            "playerNumber" => 4,
        ],
        [
            "scores" => array_values($player5score),
            "totalScore" => 0,
            "position" => 0,
            "playerNumber" => 5,
        ],
    ];


    foreach($players as $outerKey => $player) {

        foreach($player["scores"] as $key => $score)
            $players[$outerKey]["totalScore"] += ($key + 1) * $score;

    }

    $totalScoresSorted = array_column($players, "totalScore", NULL);
    asort($totalScoresSorted);
    $counter = 1;

    foreach($totalScoresSorted as $playerKey => $score)
        $players[$playerKey]["position"] = $counter++;


    uasort($players, function($a, $b){
        if($a["position"] == $b["position"])
            return $a["playerNumber"] > $b["playerNumber"] ? 1 : -1;
        return $a["position"] > $b["position"] ? 1 : -1;
    });


    foreach($players as $playerKey => $player)
        echo $player["position"] . ". position: " . $player["playerNumber"] . "<br>";

?>

输出:

1. position: 5
2. position: 3
3. position: 4
4. position: 1
5. position: 2

编辑2:

事实证明,你想要从头到尾排序你的分数。所以我再次更改了代码,但数组保持不变,期望您不再需要总分。

现在我只是比较最终值,如果它们不相同,我已经可以返回得分较低的那个。

如果相同,我会从结尾开始直到值不同。然后我检查两个阵列是否相同,如果是,我按播放器编号选择顺序。否则我再次返回得分较低的那个。

对数组进行排序后,我只需要再次遍历数组并为每个玩家设置位置。

<?php

    $player1score = array(3,3,3,3,4,3);
    $player2score = array(3,3,3,3,3,2);
    $player3score = array(3,3,3,3,2,3);
    $player4score = array(3,3,3,3,3,3);
    $player5score = array(3,3,3,2,2,3);

    $players = [
        [
            "scores" => array_values($player1score),
            "position" => 0,
            "playerNumber" => 1,
        ],
        [
            "scores" => array_values($player2score),
            "position" => 0,
            "playerNumber" => 2,
        ],
        [
            "scores" => array_values($player3score),
            "position" => 0,
            "playerNumber" => 3,
        ],
        [
            "scores" => array_values($player4score),
            "position" => 0,
            "playerNumber" => 4,
        ],
        [
            "scores" => array_values($player5score),
            "position" => 0,
            "playerNumber" => 5,
        ],
    ];



    uasort($players, function($a, $b) {
        $scoresA = array_reverse($a["scores"]);
        $scoresB = array_reverse($b["scores"]);
        $i = 0;

        if($scoresA[$i] != $scoresB[$i])
            return $scoresA[$i] > $scoresB[$i] ? 1 : -1;

        while(isset($scoresA[$i], $scoresB[$i]) && $scoresA[$i] == $scoresB[$i])$i++;

        if(!isset($scoresA[$i]) || !isset($scoresB[$i]))
            return $a["playerNumber"] > $b["playerNumber"] ? 1 : -1;
        return $scoresA[$i] > $scoresB[$i] ? 1 : -1;
    });


    $counter = 1;
    foreach($players as $playerKey => $score)
        $players[$playerKey]["position"] = $counter++;


    foreach($players as $playerKey => $player)
        echo $player["position"] . ". position: " . $player["playerNumber"] . "<br>";

?>

输出:

1. position: 2
2. position: 5
3. position: 3
4. position: 4
5. position: 1

答案 1 :(得分:0)

这应该做你以后的事情:

$scores = array(
    'Player 1' => array(3,3,3,3,4,3),
    'Player 2' => array(3,3,3,3,3,4),
    'Player 3 '=> array(3,3,3,3,2,3),
    'Player 4' => array(3,3,3,3,3,3),
    'Player 5' => array(3,3,3,2,2,3),
);

// should be set to total number of scores in each array
$total = 6;

$sorted_scores = array();

$i = $total;
while( $i > 0 )
{
    // decrement counter
    $i--;

    // get the current round's scores
    $this_scores = array();
    foreach( $scores as $player => $score_set )
    {
        $this_scores[$player] = $score_set[$i];
    }

    // clear duplicates
    $this_scores_values = array_count_values($this_scores);
    foreach( $this_scores as $player => $score )
    {
        if( $this_scores_values[$score] > 1 )
        {
            unset($this_scores[$player]);
        }
        else
        {
            // if this isn't a duplicate, remove from the main array so we don't re-use this player
            unset($scores[$player]);
        }
    }

    // sort remaining scores, low to high
    uasort($this_scores, function($a, $b)
    {
        if( $a < $b )
        {
            return -1;
        }

        return 1;
    });

    // add to sorted scores
    $sorted_scores = array_merge($this_scores, $sorted_scores);
}

print_r($sorted_scores);

唯一没有办法处理的是球员在整个过程中都有重复得分的情况。也许扩展它以包括检查最后留在得分数组中的任何人,并以任何顺序将它们添加到排序得分数组。