Найти наибольшее значение в многомерном массиве

19

Проблема

У меня есть многомерный массив, подобный приведенному ниже. То, что я пытаюсь достичь, - это способ найти и извлечь из массива значение с самым высоким значением «Всего», теперь я знаю, что есть функция с именем max , но это не работает с многомерным массивом, подобным этому.

То, что я думал о создании, - это создать цикл foreach и создать новый массив только с итоговыми значениями, а затем использовать max , чтобы найти максимальное значение, которое будет работать, единственная проблема будет тогда извлекать остальную часть данные, которые относятся к этому максимальному значению. Я не уверен, что это самый эффективный способ.

Любые идеи?

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

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

    [2] => Array
        (
            [Key3] => Key3
            [Total] => 39
        )
)
    
задан Karl 27.06.2013 в 11:25
источник
  • Если вам не нужна такая производительность - две петли будут хорошими. Если вы хотите получить огромное увеличение производительности в массивах с действительно большим количеством элементов, вы должны использовать интервальные деревья (сегментные деревья) для хранения значений. Но это огромная теория и может не понадобиться в вашем случае. –  Kamen Stoykov 27.06.2013 в 11:38

8 ответов

13

Это так основной алгоритм.

$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);

Рабочая демонстрация

    
ответ дан Robert 27.06.2013 в 11:40
источник
  • Почему вы инициализируете $ max с -9999999? –  halfpastfour.am 24.10.2014 в 11:03
  • Вы можете инициализировать его с помощью «$ max = ~ PHP_INT_MAX;» Проверьте основы поиска минимального числа. Другой вариант - инициализировать его первым элементом массива –  Robert 24.10.2014 в 16:07
  • Нет, мой вопрос был почему? –  halfpastfour.am 27.10.2014 в 14:12
  • , потому что вам нужно иметь минимальное значение для сравнения с первого раза, и вам нужно быть уверенным, что это значение меньше первого элемента. Это можно сделать и с помощью первого элемента массива, но тогда мне нужно будет запустить цикл из второго элемента в массиве. –  Robert 27.10.2014 в 16:05
  • Вы всегда можете просто инициализировать его как $ max = null; затем просто добавьте еще одно условие, чтобы проверить, что $ max уже установлен, например if ($ v ['Total']> $ max ||! $ max). В этом случае при первом запуске цикла и отсутствии значения $ max оно будет установлено. Предполагается, что даже если это единственное значение, это будет технически максимальным независимо от любого произвольного минимума, который вы жестко закодировали. –  Mike 25.01.2018 в 21:23
Показать остальные комментарии
24

С PHP 5.5 вы можете использовать array_column , чтобы получить массив значений для определенного ключа и max.

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

ответ дан Astrus 11.04.2017 в 14:20
источник
  • Это работает для меня :) –  Jonjie 28.09.2017 в 04:35
19

Просто сделайте simple loop и сравните значения или используйте array_reduce

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

print_r($data);

Смотрите Live Demo

    
ответ дан Baba 27.06.2013 в 11:30
источник
  • Хотя использование @ вместо проверки того, действительно ли действительно существует, является плохой практикой, это, безусловно, самый правильный ответ. array_reduce предназначен для таких решений. –  halfpastfour.am 24.10.2014 в 11:02
4

Я знаю, что этот вопрос старый, но я предоставляю следующий ответ в ответ на другой вопрос, который указал здесь после того, как он был помечен как дубликат. Это еще одна альтернатива, о которой я не упоминал в текущих ответах.

  

Я знаю, что есть функция 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] .

    
ответ дан mister martin 27.12.2016 в 16:55
источник
2

другой простой метод будет

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

print_r( max( $max ) );
    
ответ дан bystwn22 27.06.2013 в 13:16
источник
1

Вы можете использовать функцию php usort: Ссылка

Симпатичный иллюстративный пример приведен ниже:

<?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";
}

& GT;?

Таким образом, он будет сортировать максимальное значение для последнего индекса массива.

Вывод:

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

Этот пример приведен на вышеупомянутой ссылке

    
ответ дан Umair Khan 27.06.2013 в 11:34
источник
  • Я бы не рекомендовал использовать сложный алгоритм сортировки для чего-то вроде получения одного значения из массива. Собственно, сортировка должна выполняться только тогда, когда это действительно необходимо. Дополнительные накладные расходы не стоят «крутого» решения. –  Marcello Mönkemeyer 11.10.2016 в 10:09
  • @ MarcelloMönkemeyer, какие именно дополнительные накладные расходы вы имеете в виду здесь? Чтобы получить одно значение (макс. Или мин.), Весь массив должен быть пройден (путем сравнения). Функция выше также делает то же самое, если я не вижу что-то здесь! –  Umair Khan 12.10.2016 в 17:25
  • Фактическая сортировка, поскольку она требует нескольких обходов и сравнений, а также многократного перемещения и изменения расположения ключей массива. В зависимости от реализованного алгоритма сортировки (к сожалению, я не знаю, какой из них использует PHP), это может расти экспоненциально. Это может быть не очень заметным различием для небольших массивов и при использовании несколько раз, но представьте, что он постоянно используется в рамках, таких как Symfony или Laravel - это будет огромный облом. –  Marcello Mönkemeyer 13.10.2016 в 15:48
1

Может быть выполнено с помощью 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;
    }
});
    
ответ дан katona.abel 20.04.2017 в 09:12
источник
1
<?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);
    
ответ дан Nabi K.A.Z. 12.11.2017 в 11:40
источник