PHP检索2D关联数组中的最小值和最大值

时间:2009-08-28 06:19:23

标签: php arrays loops max minimum

我有一个这种格式的数组:

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'的最小值和最大值?我可以使用几个循环来做到这一点,但我认为可能有更好的方法。

8 个答案:

答案 0 :(得分:6)

与其他人发布的内容相比,您无法使用min() / max()函数来解决此问题,因为这些函数无法理解传入的数据结构(数组)。这些函数仅适用于标量数组元素。


开始编辑

使用min()max()似乎产生正确答案的原因与将数组类型转换为整数是undefined behaviour

  

转换为整数的行为   未定义其他类型。不要   依赖于任何观察到的行为   如有变更,恕不另行通知。

我上面关于类型转换的陈述是错误的。实际上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
 */

转换为OP的问题,这表明直接使用min()max()似乎产生正确结果的原因。数组的第一个元素是id - 值,因此min()max()会先对它们进行比较,然后产生正确的结果,因为最低id是一个最低count和最高idcount最高的那个。

结束编辑


正确的方法是使用循环。

$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']);
}

答案 1 :(得分:0)

您可以使用max()min()功能。

答案 2 :(得分:0)

您可以使用max / min函数,因为它们将返回包含每个索引的最大值/最小值的数组。您的示例应返回array(189, 'Networking ', 48) max。然后你可以从该数组中获取计数。


更新此功能不起作用,因为我已经例外。手册页示例具有误导性,示例使用max给出正确的结果,但这只是巧合。

答案 3 :(得分:0)

你用几个循环做了什么?一个就够了:)

  1. 获取第一个元素,将计数分配给$ min和$ max
  2. 迭代其余部分,比较每个$ min和$ max的数量,如果更小/更大,则分配新的计数值

答案 4 :(得分:0)

看起来你不能在2D数组上使用max()。它只返回最大的数组,而不是每个索引的max()(在几个答案中提到)。

所以:

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

答案 5 :(得分: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

答案 6 :(得分:0)

如果所需的列是数组中的第一个,则可以使用以下单行:

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

这将找到 id

的最小值/最大值

答案 7 :(得分:0)

从前面的回答中可以看出,有许多可行的技术需要考虑。

如果您正在考虑最佳性能,那么您应该尽量减少使用的循环次数和函数调用次数。

“在幕后”,原生函数 min()max() 将完全迭代它们所提供的数组。因此,如果您使用函数或构造循环遍历二维输入数组,然后调用 min(),然后调用 max(),您将分别迭代输入数组的全长三次。< /p>

考虑这个只迭代 1 次的代码片段:

代码:(Demo)

$min = array_shift($array)['count'] ?? null;
$max = $min;
foreach ($array as $row) {
    if ($min > $row['count']) {
        $min = $row['count'];
    }
    if ($max < $row['count']) {
        $max = $row['count'];
    }
}
var_export(['min' => $min, 'max' => $max]);
  • 以上的优点是
    • 只有 1 个函数调用(提取第一行的数据)和一个循环
    • 它不会多次遇到相同的数据
    • 简单的数字比较对于 php 执行来说非常简单/快速
  • 以上的缺点是
    • 它通过调用 array_shift() 来改变输入数组,所以如果你在同一个范围内重复使用数组,它将不再包含第一个值
    • 它比其他一些技术更冗长,并且忽略了一些可行的本机功能

另一种技术重视功能风格的代码。 PHP 具有本机函数,可以使这项任务井然有序。

array_column() 可以隔离 count 列中的所有值。 min() 返回最小的数字。 max() 返回最高数字。

代码:(Demo)

$counts = array_column($array, 'count');
var_export(['min' => min($counts), 'max' => max($counts)]);
  • 以上的优点是
    • 只有 1 个临时变量
    • 它不会改变输入数组
    • 非常简洁、直观和声明式的编码风格
    • 如果其中一行缺少 count 元素,它不会生成任何警告
  • 以上的缺点是
    • 从技术上讲,它对数据进行了 3 次迭代
    • 很可能比第一个片段的表现更差