2017-01-05 27 views
0

對於數組如比較關聯數組值的高效的方法:不使用的foreach

$array = array(
    735 => array('name'=>'Alpha', 'num'=>1), 
    584 => array('name'=>'Beta', 'num'=>4), 
    857 => array('name'=>'Gamma', 'num'=>1), 
    982 => array('name'=>'Delta', 'num'=>2) 
); 

這將是用於過濾與的num至少值元素的最佳方式。也就是說,在這種情況下,該解決方案將是以下數組:

array(
    735 => array('name'=>'Alpha', 'num'=>1), 
    857 => array('name'=>'Gamma', 'num'=>1) 
); 

我知道,這可以通過foreach環路和最小值的跟蹤做,但我希望會有一些數組函數可以完成這項工作。

我目前的做法是:

$num_values = array(); 
foreach($array as $id => $meta) 
{ 
    $num_values[] = $meta['num']; 
} 
$min_num_value = min($num_values); 

$filtered_array = array(); 
foreach($array as $id => $meta) 
{ 
    if($meta['num'] == $min_num_value) 
    { 
     $filtered_array[$id] = $meta; 
    } 
} 
print_r($filtered_array); 

,正如你所看到的,顯然不是去了解任務的最佳方式。

+0

downvoter,小心解釋一下? – asprin

回答

3

優化與最小值計算和O(n)的複雜性過濾的版本。

$array = array(
    735 => array('name'=>'Alpha', 'num'=>1), 
    584 => array('name'=>'Beta', 'num'=>4), 
    857 => array('name'=>'Gamma', 'num'=>1), 
    982 => array('name'=>'Delta', 'num'=>2) 
); 

$minValue  = PHP_INT_MAX; 
$filteredArray = []; 
foreach ($array as $key=>$data) { 
    $itemNumber = $data['num']; 
    if ($itemNumber < $minValue) { 
     $filteredArray = [$key => $data]; 
     $minValue  = $itemNumber; 
    } elseif ($itemNumber === $minValue) { 
     $filteredArray[$key] = $data; 
    } 
} 

var_dump($filteredArray); 

foreach性能比任何array_xxx()功能加上關閉/函數調用更好。所以,即使對於大數組,這種解決方案也必須有效。

+0

確認。對於大型(5M行)數據集,Microbenchmark顯示我提高了50%(與兩個循環相比)。 – Timurib

+0

我看到一些我在'[$ key => $ data]'之前從未見過的東西。那是PHP7的語法? – asprin

+0

短陣列語法,自PHP 5.4起可用 – Timurib

0

由於min只給出一條記錄,你可以嘗試這樣:它會先刪除foreach循環,其餘的是你的。

$array = array(
     735 => array('name'=>'Alpha', 'num'=>1), 
     584 => array('name'=>'Beta', 'num'=>4), 
     857 => array('name'=>'Gamma', 'num'=>1), 
     982 => array('name'=>'Delta', 'num'=>2) 
); 
$val = min($array); 
$filtered_array=array(); 
foreach($array as $id => $meta) 
{ 
    if($meta['num'] == $val['num']) 
    { 
     $filtered_array[$id] = $meta; 
    } 
} 
print_r($filtered_array); 
+0

'min($ array)' - 它取最低的索引值,即584 ..而我希望num# – asprin

+0

的最小值參見:http://php.net/manual/en/function.min。 php –

0

這可能會幫助你

$arr = array(
    735 => array('name'=>'Alpha', 'num'=>1), 
    584 => array('name'=>'Beta', 'num'=>4), 
    857 => array('name'=>'Gamma', 'num'=>1), 
    982 => array('name'=>'Delta', 'num'=>2) 
); 

$inventory = array_map("array_values", $arr); 
usort($inventory, function ($item1, $item2) { 
    if ($item1[1] == $item2[1]) return 0; 
    return $item1[1] < $item2[1] ? -1 : 1; 
}); 

echo "<pre>";print_r($inventory);