php - 使用自定义排序顺序对数组进行排序,最后一个值

标签 php arrays sorting multidimensional-array

我正在尝试对多维数组进行排序,并且始终在数组末尾有一个值。该数组应按“unitText”排序(不关心unitID如何排序),但始终将“Last”作为数组中的最后一个值。我快要明白了,但还没有完全明白。

<?php

function cmp($a, $b)
{
    /*
    $a = preg_replace('@^(Last) @', '', $a);
    $b = preg_replace('@^(Last) @', '', $b);
    return strcasecmp($a, $b);
    */

    if(strtolower(substr($a['unitText'],0,4))=="last") return strnatcmp($a['unitText'],9999);
    else if(strtolower(substr($b['unitText'],0,4))=="last") return strnatcmp(9999,$b['unitText']);
    else return strnatcmp($a, $b);

    //return strnatcmp($a['unitText'], $b['unitText']);

    //return end($a) > end($b);

}

$unit = array(
    array("unitID"=>80, "unitText"=>"Q701"),
    array("unitID"=>30, "unitText"=>"H568"),
    array("unitID"=>25, "unitText"=>"Last"),
    array("unitID"=>40, "unitText"=>"Z255"),
    array("unitID"=>20, "unitText"=>"A459")
);

echo "<pre>";
print_r($unit);
echo "</pre>";

echo "<hr/>";

//uksort($unit['unitText'], "cmp");
//array_multisort($unit['unitText'], SORT_DESC, $unit['unitID'], SORT_ASC, $unit);
usort($unit, 'cmp');

echo "<pre>";
print_r($unit);
echo "</pre>";

?>

最终应该是:

Array
(
    [0] => Array
        (
            [unitID] => 20
            [unitText] => A459
        )

    [1] => Array
        (
            [unitID] => 30
            [unitText] => H568
        )

    [2] => Array
        (
            [unitID] => 80
            [unitText] => Q701
        )

    [3] => Array
        (
            [unitID] => 40
            [unitText] => Z255
        )

    [4] => Array
        (
            [unitID] => 25
            [unitText] => Last
        )

)

我做错了什么?

最佳答案

您的问题出在这一行:

else return strnatcmp($a, $b);

请记住,$a$b 都是数组,但 strnatcmp() 比较字符串。调用此函数时,您的两个数组将隐式转换为字符串,它们的值都是Array,因此它们将返回相等且不会被排序。

您应该比较 unitText 值:

else return strnatcmp($a['unitText'], $b['unitText'])

您没有看到这一点的事实告诉我,您在开发中没有将 error_reporting 级别设置得足够高,因为隐式转换会发出 E_NOTICE当它发生时。在开发中,您应该始终设置 error_reporting(E_ALL | E_STRICT); (无论是在代码的入口点,还是在 php.ini 等),以便任何小问题都会立即标记出来供您修复。

此外,当其中一个值是“Last”时,您根本没有理由调用 strnatcmp(),因为您已经知道该值应该是最后一个。只需返回 1-1 (具体取决于哪个包含“Last”)并完成它。

最后,您不需要代码中的所有 else 条件。由于所有路径都会发出 return,因此您可以假设仅当比较失败时才会执行 if block 之后的任何内容:

if (strtolower(substr($a['unitText'],0,4))=="last") {
  return 1;
}

if strtolower(substr($b['unitText'],0,4))=="last") {
  return -1;
}

return strnatcmp($a['unitText'], $b['unitText']);

在上面,第二个 if 仅当我们在 $a 中没有找到“Last”时才执行,因为如果有,该函数就已经结束了。同样,最后的 return 语句(使用 strnatcmp() 调用)仅在上述两个 if 条件均未通过时执行,因为以下任一条件他们会返回一个值并结束函数。

这是一件小事,但嵌套一堆不需要的 ifelse block 会降低代码的可读性。

关于php - 使用自定义排序顺序对数组进行排序,最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7116315/

相关文章:

php - 如何在 Godaddy 虚拟主机服务器中使用 cron 作业运行 Yii2 的控制台命令

php - 使用 codeigniter 传递下拉列表的字符串值

php - MySQL数据库设计困惑|权限

mysql - 如何将以下信息合并到 1 个 mysql 查询中?

bash - 仅按月份名称和日期排序。狂欢

Python 按数组 a 分组,并汇总数组 b - 性能

php - 如何避免 undefined index

c++ - 在 C++ 中创建堆上的结构数组

ruby - 就地修改数组 - Ruby

javascript - Laravel - 将 php 变量作为数组传递给 JS