PHP Получить минимальное и максимальное значения в двумерном ассоциативном массиве - PullRequest
8 голосов
/ 28 августа 2009

У меня есть массив в этом формате:

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
        )

)

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

Ответы [ 7 ]

6 голосов
/ 28 августа 2009

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


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

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

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

Мое утверждение выше о приведении типов было неверным. На самом деле 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 голосов
/ 16 февраля 2011

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

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

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

0 голосов
/ 07 октября 2009

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

/**
 * 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 голосов
/ 28 августа 2009

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

Итак:

$count = array();
foreach($arr as $_arr) {
    $count[] = $_arr['count'];
}
var_dump(max($count), min($count));
0 голосов
/ 28 августа 2009

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

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

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


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

0 голосов
/ 28 августа 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...