2016-08-04 25 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

我重建了一個流程,使用索引文件以所描述的方式使用「預先分類的流」,它的運行速度*比其前身快*三倍,包括排序時間! –