2009-08-28 2 views
8

У меня есть массив в следующем формате:PHP Получить минимальное и максимальное значения в 2D ассоциативный массив

Array 
(
    [0] => Array 
     (
      [id] => 117 
      [name] => Networking 
      [count] => 16 
     ) 

    [1] => Array 
     (
      [id] => 188 
      [name] => FTP 
      [count] => 23 
     ) 

    [2] => Array 
     (
      [id] => 189 
      [name] => Internet 
      [count] => 48 
     ) 

) 

Есть хороший способ получить минимальные и максимальные значения «количество»? Я мог бы сделать это, используя несколько циклов, но я думал, что может быть лучший способ.

+0

+1 Я столкнулся с этой проблемой сегодня, и я просто сделал цикл. Любопытно, какие существуют другие методы. – MitMaro

+0

Если есть какая-то функция, которая сделает это, она будет реализована с помощью циклов, так что же так плохо, используя ваши собственные функции ?! –

+0

@ Светлозар Ангелов: Для функций PHP петли будут записаны на C, а не на PHP, поэтому они, как правило, быстрее. –

ответ

6

в отличии от того, что другие выложили, вы не можете использовать функции в min()/max() этой проблемы, поскольку эти функции не понимают структуру данных (массив), которые прошли в. эти только функциях работа для элементов скалярного массива.


НАЧАТЬ РЕДАКТИРОВАНИЕ

Причина, почему использование min() и max(), кажется, дают правильный ответ связан тип-литейные массивы целых чисел, является undefined behaviour:

Поведение преобразования в целое число не определено для других t ypes. Не следует полагаться на любое наблюдаемое поведение, так как он может быть изменен без предварительного уведомления.

Мое высказывание выше о типовом литье было неправильным. Фактически min() и max() работают с массивами, но не в том, как OP нуждается в их работе. При использовании min() и max() с несколькими массивами или массив массивов элементов сравниваются поэлементно слева направо:

$val = min(array(2, 4, 8), array(2, 5, 1)); // array(2, 4, 8) 
/* 
* first element compared to first element: 2 == 2 
* second element compared to second element: 4 < 5 
* first array is considered the min and is returned 
*/ 

В переводе на проблемы в ФП в этом показывает причину, почему прямое использование min() и max(), кажется, дать правильный результат.Первые элементы массивов являются id -значения, поэтому min() и max() будет сравнивать их первый, кстати в результате правильного результата, так как низкий id является один с самым низким count и самой высокой id является один с самым высоким count.

END EDIT


Правильный путь будет использовать цикл.

$a = array(
     array('id' => 117, 'name' => 'Networking', 'count' => 16), 
     array('id' => 188, 'name' => 'FTP', 'count' => 23), 
     array('id' => 189, 'name' => 'Internet', 'count' => 48) 
); 
$min = PHP_INT_MAX; 
$max = 0; 
foreach ($a as $i) { 
    $min = min($min, $i['count']); 
    $max = max($max, $i['count']); 
} 
+0

На странице руководства для max '$ val = max (массив (2, 4, 8), массив (2, 5, 7)); // array (2, 5, 7) '. Прочтите. – MitMaro

+0

Ваш ответ правильный, хотя и не по той причине, о которой вы говорили. 'min' и' max' правильно обрабатывают массивы и не бросают их в целые числа, в руководстве дается более подробная информация. – MitMaro

+0

@ MitMaro: Вы правы - мое предположение или рассуждение об использовании массивов в min() и max() было неправильным. Я отредактировал свой ответ и удалил неправильный оператор. –

0

Вы можете использовать функции max() и min().

+1

+1 потому что это привело меня к моему ответу. – MitMaro

0

Вы можете использовать функции max/min, поскольку они возвратят массив, содержащий максимум/минимум каждого индекса. Ваш пример должен вернуть array(189, 'Networking ', 48) за max. Затем вы можете захватить счет из этого массива.


Обновление не работает, как и я. Пример справочной страницы вводит в заблуждение, а пример дает правильный результат с использованием max, но это просто совпадение.

+1

Чтобы быть более конкретным, он фактически вернет правильно отображенные ключи - так что вы можете сделать 'max ($ array) ['count']' и 'min ($ array) ['count']' – Amber

+1

Dav: I когда я попробую это сделать. Возможно, вы думаете о Питоне. – MitMaro

+0

Возможно, вам стоит перечитать вопрос MitMaro! : P –

0

Что вы сделали с несколькими петлями? Один из них вполне достаточно :)

  1. Получить первый элемент, Ассинг отсчет времени до и $ мин и $ макс
  2. итерация над остальными, сравнить сосчитать до каждого $ мин и $ макс, если меньше/больше, присвоить новое значение счетчика
0

Похоже, вы не можете использовать max() для 2D-массива. Он просто возвращает наибольший массив, а не max() каждого индекса (как указано в нескольких ответах).

Итак:

$count = array(); 
foreach($arr as $_arr) { 
    $count[] = $_arr['count']; 
} 
var_dump(max($count), min($count)); 
0

Есть ли эквивалент встроенный функция этой? (даже без теста способности к)

 
/** 
* extracts a column from a 2D array, with an optional selection over another column 
* 
* @param $aArray  array to extract from 
* @param $aColName name of the column to extract, ex. 'O_NAME' 
* @param $aColTest (optional) name of the column to make the test on, ex. 'O_ID' 
* @param $aTest  (optional) string for the test ex. ">= 10", "=='".$toto."'" 
* @return   1D array with only the extracted column 
* @access public 
*/ 

function extractColFromArray($aArray, $aColName, $aColTest="", $aTest="") { 
    $mRes = array(); 
    foreach($aArray as $row) { 
    if (($aColTest == "") || (eval("return " . $row[$aColTest] . $aTest . ";"))) { 
    $mRes[] = $row[$aColName]; 
    } 
    } 
    return $mRes; 
} // extractColFromArray 
0

Если нужный столбец первого в массиве вы можете использовать следующие остроты:

$max = max(array_map('current', $a)); 
$min = min(array_map('current', $a)); 

Найдет мин/макс id

Смежные вопросы