获取数组列中的最小值和最大值

Posted

技术标签:

【中文标题】获取数组列中的最小值和最大值【英文标题】:Get the minimum and maximum values in an array column 【发布时间】:2010-11-23 15:17:54 【问题描述】:

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

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

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

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

【问题讨论】:

+1 我今天遇到了这个问题,我只是做了一个循环。好奇还有什么其他方法。 如果有一些函数可以做到这一点,它将通过循环实现,那么使用你自己的函数有什么不好?! @Svetlozar Angelov:对于 php 函数,循环将用 C 而非 PHP 编写,因此它们通常更快。 【参考方案1】:

与其他人发布的相比,您不能使用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-values,因此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']);

【讨论】:

来自 max $val = max(array(2, 4, 8), array(2, 5, 7)); // array(2, 5, 7) 的手册页。阅读它。 您的答案是正确的,但不是因为您所说的原因。 minmax 正确处理数组并且不要将它们转换为整数,手册提供了更多详细信息。 @MitMaro:你是对的——我对在 min() 和 max() 中使用数组的假设或推理是错误的。我编辑了我的答案并删除了错误的陈述。 作为“锡箔帽”参数,如果输入数组为空,这个答案将返回不正确的结果。当然,我不知道 OP 的应用程序是否可以传入一个空数组。这只是对研究人员的警告。【参考方案2】:

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

【讨论】:

这充其量只是部分答案。【参考方案3】:

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

    获取第一个元素,将计数分配给 $min 和 $max 遍历其余部分,将 count 与每个 $min 和 $max 进行比较,如果更小/更大,则分配新的 count 值

【讨论】:

这似乎解释得很好,但是如果没有 sn-p,研究人员可能无法按照您的意图实施您的建议。您可能会或可能不会在我的回答中认可第一个 sn-p。如果你有不同的看法,也许在你的答案中添加一个 sn-p 并解释你为什么会以你独特的方式去做。【参考方案4】:

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

所以:

$count = array();
foreach($arr as $_arr) 
    $count[] = $_arr['count'];

var_dump(max($count), min($count));

【讨论】:

【参考方案5】:

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

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

这将找到 id

的最小值/最大值

【讨论】:

为什么要调用array_map() 两次以获得相同的返回值?这缺乏效率,也不是 D.R.Y.【参考方案6】:

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

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

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

考虑这个只迭代 1 次的 sn-p:

代码:(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 次 它的性能很可能比第一个 sn-p 差

【讨论】:

【参考方案7】:

是否有与之等效的内置功能? (即使没有 test 能力)

/** * 从二维数组中提取一列,可选择另一列 * * @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

【讨论】:

这个 sn-p 在 2-dim 数组中找不到最小值和最大值。这不是这个问题的正确答案。

以上是关于获取数组列中的最小值和最大值的主要内容,如果未能解决你的问题,请参考以下文章

从Awk中的多维数组中的子数组获取最小值和最大值

sql MIN()和MAX()允许您从表中的列中提取最小值和最大值。第1行显示MIN()示例,它选择最小值

从具有 O(n) 的数组中获取最大的时间下降、最小值和最大值

java程序,随机产生包含20个元素的数组,求出数组中的最大值,最小值和平均值

Pyspark - 从具有最小值和最大值范围的数组中获取值

如何在 NSString/String 数组中获取最小值和最大值?