2016-08-04 28 views
3

我有一组对象,它们是足球运动员。数组可以包含从零到数千个玩家的任何东西。我想将其降低到最好的10.我的初步尝试如下:将对象数组降至“最好的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]); 
} 

正如你可能会说,我不明白我在这一点上做什么,不了解$关键部分是什么(它只是从其他的例子复制)。它仍然挂在PC上。

我该如何改正这个问题,或者有没有更好的方法来达到这个目的呢?

为了响应数据结构的请求,这里是一个只有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 
      ) 

    ) 
+0

您可以发布的数据结构,请 – Kisaragi

+0

更新的问题,显示的数据结构。希望这就是你想要的? – Farflame

回答

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

哇,这太简单了,第一次工作。也非常快。谢谢:) – Farflame

2

我想有可能是一个更简单的方法。

如何按照技能水平(降序)排序,然后“切分”前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; 
} 
+0

谢谢,你说得对,这是一个更好的方法。处理速度非常快,并且工作完美。 – Farflame

+0

由于人们很快就会知道何时需要处理*穿孔卡(!)上的数据,因此排序是一个“意外高效”的过程。如果您要求所使用的所有数据流都按相同的顺序排列,那么许多大批量操作都可以非常有效地执行(即使您仅限于冲卡或磁带,就像以前的人一样) 。可能需要“索引文件”(它们不具有...)*的进程可以按顺序完成* ...产生“也仍然排序”的输出。 –

+0

我重建了一个流程,使用索引文件以所描述的方式使用“预先分类的流”,它的运行速度*比其前身快*三倍,包括排序时间! –