2013-06-27 84 views
18

的問題在多維數組找出最大值

我有類似下面的一個多維數組。我試圖實現的是一種方法來查找和檢索數組中最高的「總」值,現在我知道有一個函數稱爲max,但不適用於這樣的多維數組。

我想過要做的是創建一個foreach循環,然後用總數構建一個新數組,然後使用max來查找最大值,這將起作用,唯一的問題是檢索剩餘的與最大值有關的數據。我不確定這是最有效的方法。

任何想法?

Array 
(
    [0] => Array 
     (
      [Key1] => Key1 
      [Total] => 13 
     ) 

    [1] => Array 
     (
      [Key2] => Key2 
      [Total] => 117 
     ) 

    [2] => Array 
     (
      [Key3] => Key3 
      [Total] => 39 
     ) 
) 
+0

搜索的數組如果你不需要這樣的表現來完成 - 兩個循環會很好。如果你想在數組中有非常多的性能增益,你應該使用Interval Trees(Segment Trees)來存儲值。但這是一個巨大的理論,可能不需要你的情況。 –

回答

11

它是如此基本的算法給出。

$max = -9999999; //will hold max val 
$found_item = null; //will hold item with max val; 

foreach($arr as $k=>$v) 
{ 
    if($v['Total']>$max) 
    { 
     $max = $v['Total']; 
     $found_item = $v; 
    } 
} 

echo "max value is $max"; 
print_r($found_item); 

Working demo

+0

爲什麼要用'-9999999'初始化'$ max'? –

+0

你可以用「$ max =〜PHP_INT_MAX;」來初始化它。檢查尋找最小號碼的基礎知識。另一個選項是初始化數組的第一個成員 – Robert

+0

不,我的問題是爲什麼? –

18

只是做了simple loop和比較值或使用array_reduce

$data = array_reduce($data, function ($a, $b) { 
    return @$a['Total'] > $b['Total'] ? $a : $b ; 
}); 

print_r($data); 

See Live Demo

+5

儘管使用'@'而不是檢查一個值是否真的存在是不好的做法,這是迄今爲止最正確的答案。 'array_reduce'意味着這些解決方案。 –

0

您可以使用PHP usort功能: http://php.net/manual/en/function.usort.php

一個漂亮的說明性的例子在這裏給出:

<?php 
function cmp($a, $b) 
{ 
return strcmp($a["fruit"], $b["fruit"]); 
} 

$fruits[0]["fruit"] = "lemons"; 
$fruits[1]["fruit"] = "apples"; 
$fruits[2]["fruit"] = "grapes"; 

usort($fruits, "cmp"); 

while (list($key, $value) = each($fruits)) { 
echo "\$fruits[$key]: " . $value["fruit"] . "\n"; 
} 

?>

因此,這將排序的最大值到最後一個數組索引。

輸出:

$fruits[0]: apples 
$fruits[1]: grapes 
$fruits[2]: lemons 

這個例子是在上述鏈接

+0

我不會推薦使用複雜的排序算法來獲取數組中的單個值。實際上,排序只能在真正需要的時候完成。額外的開銷不值得一看「酷炫」的解決方案。 –

+0

@MarcelloMönkemeyer這裏提到的額外開銷是多少?要獲得單個值(最大值或最小值),需要遍歷整個數組(通過比較)。上面的功能也做同樣的事情,除非我在這裏錯過了一些東西! –

+0

實際的排序,因爲它需要多次遍歷和比較以及重複移動和重新定位數組鍵。根據實施的排序算法(不幸的是,我不知道哪一個PHP使用),這可以增長指數。它對小數組可能沒有任何可見的區別,並且在使用很少的時候,但是想象它在像Symfony或Laravel這樣的框架中經常被使用 - 這會是一種非常大的失望。 –

1

另一種簡單的方法將是

$max = array_map(function($arr) { 
    global $last; 
    return (int)(($arr["Total"] > $last) ? $arr["Total"] : $last); 
}, $array); 

print_r(max($max)); 
3

我知道這個問題是舊的,但我提供了以下的答案響應於指出被標記後,這裏的另一個問題作爲副本。這是我在目前的答案中沒有看到的另一種選擇。

我知道有一個稱爲max的函數,但不能用這樣的多維數組工作。

讓您可以與array_column這使得獲得最大的價值很容易:

$arr = [['message_id' => 1, 
      'points' => 3], 
     ['message_id' => 2, 
      'points' => 2], 
     ['message_id' => 3, 
      'points' => 2]]; 

// max value 
$max = max(array_column($arr, 'points')); 

獲取關聯關鍵是它得到多一點棘手,考慮到你可能實際上要多鍵(如果$max匹配多個值)。你可以用裏面array_map匿名函數做到這一點,並使用array_filter刪除null值:

// keys of max value 
$keys = array_filter(array_map(function ($arr) use ($max) { 
    return $arr['points'] == $max ? $arr['message_id'] : null; 
}, $arr)); 

輸出:

array(1) { 
    [0]=> 
    int(1) 
} 

如果你結束了倍數鍵,但只關心在第一場比賽中發現,那麼只需參考$keys[0]

15

從PHP 5.5開始,您可以使用array_column來獲取特定鍵值的數組,並將其最大化。

max(array_column($array, 'Total'))

+0

這適用於我:) – Jonjie

0

可以用array_walk(array_walk_recursive如果需要的話)

$ ARR是要在

$largestElement = null; 

array_walk($arr, function(&$item, $key) use (&$largestElement) { 
    if (!is_array($largestElement) || $largestElement["Total"] < $item["Total"]) { 
     $largestElement = $item; 
    } 
}); 
0
<?php 
$myarray = array(
    0 => array(
     'Key1' => 'Key1', 
     'Total' => 13, 
    ), 
    1 => array(
     'Key2' => 'Key2', 
     'Total' => 117, 
    ), 
    2 => array(
     'Key2' => 'Key3', 
     'Total' => 39, 
    ), 
); 

$out = array(); 
foreach ($myarray as $item) { 
    $out[] = $item['Total']; 
} 

echo max($out); //117 

unset($out, $item);