8

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

$array = [
    ['id' => 117, 'name' => 'Networking', 'count' => 16],
    ['id' => 188, 'name' => 'FTP', 'count' => 23],
    ['id' => 189, 'name' => 'Internet', 'count' => 48],
];

16有没有一种很好的方法来检索“计数”列(和48分别)的最小值和最大值?

我可以使用几个循环来做到这一点,但我想知道是否有更好的方法。

4

7 回答 7

5

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


开始编辑

使用min()andmax()似乎产生正确答案的原因与将数组类型转换为整数有关,这是一种未定义的行为

对于其他类型,未定义转换为整数的行为。不要依赖任何观察到的行为,因为它可能会在没有通知的情况下发生变化。

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

结束编辑


正确的方法是使用循环。

$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']);
}
于 2009-08-28T07:24:03.467 回答
0

您可以使用max()min()函数。

于 2009-08-28T06:21:57.583 回答
0

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

  1. 获取第一个元素,将计数分配给 $min 和 $max
  2. 遍历其余部分,将 count 与每个 $min 和 $max 进行比较,如果更小/更大,则分配新的 count 值
于 2009-08-28T06:27:58.693 回答
0

看起来你不能在二维数组上使用 max() 。它只返回最大的数组,而不是每个索引的 max() (如几个答案中所述)。

所以:

$count = array();
foreach($arr as $_arr) {
    $count[] = $_arr['count'];
}
var_dump(max($count), min($count));
于 2009-08-28T10:15:29.520 回答
0

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

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

这将找到id的最小/最大值

于 2011-02-16T18:50:35.567 回答
0

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

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

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

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

代码:(演示

$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]);
  • 以上的优点是
    • 只有一个函数调用(提取第一行的数据)和一个循环
    • 它永远不会多次遇到相同的数据
    • 简单的数字比较对于 php 执行非常简单/快速
  • 以上的缺点是
    • 它通过调用来改变输入数组array_shift(),因此如果您在同一范围内重新使用该数组,它将不再包含第一个值
    • 它比其他一些技术更冗长,并且忽略了一些可行的本机功能

另一种技术重视功能样式的代码。PHP 具有使这项任务整齐工作的本机函数。

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

代码:(演示

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

是否有与该功能等效的内置功能?(即使没有测试能力)

/**
 * 从二维数组中提取一列,可选择另一列
 *
 * @param $aArray 要从中提取的数组
 * @param $aColName 要提取的列的名称,例如。'O_NAME'
 * @param $aColTest(可选)进行测试的列的名称,例如。'O_ID'
 * @param $aTest (可选) 测试字符串。">= 10", "=='".$toto."'"
 * @return 仅包含提取列的一维数组
 * @访问公共
 */

  函数 extractColFromArray($aArray, $aColName, $aColTest="", $aTest="") {
  $mRes = 数组();
  foreach($aArray as $row) {
   if (($aColTest == "") || (eval("return " . $row[$aColTest] . $aTest . ";" )) ) {
    $mRes[] = $row[$aColName];
   }
  }
  返回$mRes;
 } // extractColFromArray
于 2009-10-07T08:17:01.563 回答