将对象数组减少到“最佳10”

时间:2016-08-04 14:02:28

标签: php arrays loops foreach unset

我有一系列对象,即足球运动员。该阵列可以包含从零到数千个玩家的任何内容。我想把它减少到最好的10.我最初的尝试如下:

while (count($ArrayOfPlayers) > 10) {

    $ArrayIndex = 0;
    $WorstPlayerIndex = -1;
    $WorstPlayerSkill = 9999999999;
    foreach ($ArrayOfPlayers as $Player) {
        $Skill = $Player->RatingsArray['Skill'];
        if ($Skill < $WorstPlayerSkill) {
            $WorstPlayerIndex = $ArrayIndex;
            $WorstPlayerSkill = $Skill;
        }
        $ArrayIndex += 1;
    }

    // Found the worst player in the list, so remove him.
    unset($ArrayOfPlayers[$WorstPlayerIndex]);
}

通过阅读类似的帖子,我现在知道问题是数组实际上没有被更改,因此while循环会永远继续(计算机确实会锁定)。

因此,根据其他帖子的建议,我的修正方法如下:

while (count($ArrayOfPlayers) > 10) {

        $WorstIndexPlayer = 0;
        $WorstPlayerSkill = 9999999999;
        foreach ($ArrayOfPlayers as $key => &$Player) {
            $Skill = $Player->RatingsArray['Skill'];
            if ($Skill < $WorstPlayerSkill) {
                $WorstIndexPlayer = $key;
                $WorstPlayerSkill = $Skill;
            }
        }
        // Found the worst player in the list, so remove him.
        unset($ArrayOfPlayers[$WorstIndexPlayer]);
}

正如你可能会说的那样,我不明白我在这一点上做了什么,并且不明白$ key部分的用途(它只是从其他例子中复制而来)。它仍然只是挂起电脑。

我如何纠正这一点,还是有更好的方法来实现这一目标?

为了回应数据结构的请求,这里只展示了2名玩家,以展示他们的安排方式。

Array
(
[0] => Player Object
    (
        [ID] => 1
        [TeamID] => 1
        [Name] => Joseph Dorrington
        [RatingsArray] => Array
            (
                [Skill] => 51993
            )
    )

[1] => Player Object
    (
        [ID] => 2
        [TeamID] => 1
        [Name] => Oliver Tillyard
        [RatingsArray] => Array
            (
                [Skill] => 64574
            )

    )

2 个答案:

答案 0 :(得分:2)

使用usort,您可以先按此值对数组进行排序,然后使用array_slice获取前10个元素:

function cmp($a, $b){
    if ($a->RatingsArray['Skill'] == $b->RatingsArray['Skill']) {
        return 0;
    }
    return ($a->RatingsArray['Skill'] > $b->RatingsArray['Skill']) ? -1 : 1;
}
usort($ArrayOfPlayers, "cmp");
$ArrayOfPlayers = array_slice($ArrayOfPlayers, 0, 10);

答案 1 :(得分:2)

我认为可能有一种更简单的方法。

我们按技能等级(降序)排序的方法怎么样,然后&#34;切片&#34;第10个代表最好的?

假设你的结构看起来像这样:

$arrayOfPlayers = array (size=6)
0 => 
    object(stdClass)[1]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 1187
  1 => 
    object(stdClass)[2]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 44
  2 => 
    object(stdClass)[3]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 494
  3 => 
    object(stdClass)[4]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 584
  4 => 
    object(stdClass)[5]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 730
  5 => 
    object(stdClass)[6]
      public 'RatingsArray' => 
        array (size=1)
          'Skill' => int 613
 ...

以下代码会为您执行此操作:

// Call our custom usort function
usort($arrayOfPlayers, 'sort_players');
// Slice the array to the best 10.  Note array_slice doesn't care if there's less than 10
$best = array_slice($arrayOfPlayers, 0, 10);

// Our custom sorting function
function sort_players($a, $b) {
    if ($a->RatingsArray['Skill'] == $b->RatingsArray['Skill']) {
        return 0;
    }

    return ($a->RatingsArray['Skill'] < $b->RatingsArray['Skill']) ? 1: -1;
}