簡體   English   中英

從包含相同值的數組中獲取x個最大值

[英]Get x highest values from an array including identical values

我正在使用以下代碼從數組中檢索最高的3個數字。

$a = array(1,2,5,10,15,20,10,15);
arsort($a, SORT_NUMERIC);
$highest = array_slice($a, 0, 3);

這段代碼正確地給了我最高的三個數字array(20,15,10) ; 但是,我有興趣獲得最高的3個數字,包括相同的數字。 在這個例子中,我期望得到像array(10, 10, 15, 15, 20) 10,10,15,15,15,20)這樣的array(10, 10, 15, 15, 20)

可能會更簡單,但我的大腦卻累了。 使用arsort()首先獲得最高值,對值進行計數以獲取唯一鍵及其計數,然后對前3個進行切片(確保傳遞true以保留鍵):

arsort($a, SORT_NUMERIC);
$counts = array_slice(array_count_values($a), 0, 3, true);

然后循環這3個,並用數字值填充一個數組,計算該數組的次數並與先前的結果合並:

$highest = array();

foreach($counts as $value => $count) {
    $highest = array_merge($highest, array_fill(0, $count, $value));
}

您可以使用如下功能:

$a = array(1,2,5,10,15,20,10,15); //-- Original Array

function get3highest($a){
  $h = array(); //-- highest
  if(count($a) >= 3){ //-- Checking length
    $c = 0; //-- Counter
    while ($c < 3 || in_array($a[count($a)-1],$h) ){ //-- 3 elements or repeated value
      $max = array_pop($a);
      if(!in_array($max,$h)){
        ++$c;
      }
      $h[] = $max;
    }
    sort($h); //-- sorting
  }
  return $h; //-- values
} 
print_r(get3Highest($a));

當然,您可以改進此功能,以接受“最高”值的動態值。

以下功能可能有用

$a = array(1,2,5,10,15,20,10,15);
function getMaxValue($array,$n){ 
    $max_array = array(); // array to store all the max values
    for($i=0;$i<$n;$i++){ // loop to get number of highest values 
        $keys = array_keys($array,max($array));  // get keys
        if(is_array($keys)){ // if keys is array 
            foreach($keys as $v){  // loop array
                $max_array[]=$array[$v];  // set values to max_array
                unset($array[$v]);  // unset the keys to get next max value 
            }
        }else{ // if not array
            $max_array[]=$array[$keys]; // set values to max_array
            unset($array[$keys]); // unset the keys to get next max value
        }

    }
    return $max_array;
}
$g = getMaxValue($a,3);

輸出:

Array
(
    [0] => 20
    [1] => 15
    [2] => 15
    [3] => 10
    [4] => 10
)

您可以對其進行修改以添加條件。

我想到了其他兩種可能性。

第一:

  1. 找到前三個值中的最低值

     $min = array_slice(array_unique($a, SORT_NUMERIC), -3)[0]; 
  2. 過濾掉任何較低的值

     $top3 = array_filter($a, function($x) use ($min) { return $x >= $min; }); 
  3. 排序結果

     sort($top3); 

優點:更少的代碼
缺點:效率較低(排序,迭代整個數組,對結果排序)

第二個:

  1. 以相反的順序對數組進行排序

     rsort($a); 
  2. 迭代數組,將項目追加到結果數組,直到您追加了三個不同的項目。

     $n = 0; $prev = null; $top = []; foreach ($a as $x) { if ($x != $prev) $n++; if ($n > 3) break; $top[] = $x; $prev = $x; } 

優點:效率更高(僅排序一次,僅根據需要迭代)
缺點:更多代碼

這將按降序給出結果。 您可以選擇使用array_unshift($top, $x)代替$top[] = $x; array_unshift($top, $x) 以升序獲取它,但我想我讀過array_unshift效率較低,因為它每次添加后都會重新索引數組,因此,如果優化很重要,最好只使用$top[] = $x; array_unshift 然后以相反的順序迭代結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM