php - 对数组进行排序 - 数字、特殊字符、字母

标签 php sorting

我有数字、特殊字符和字母的数组。我如何对其进行排序,首先是数字,然后是特殊字符和字母。

$c64 = str_split(
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
);

我尝试这样做

array_multisort($l64, SORT_DESC);

但它返回特殊字符、数字和字母

最佳答案

这种事情可以通过非常“聪明”的方式来实现,所以我无法抗拒:

$c64 = str_split(
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
);

$sortValue = function($char) {
    return !ctype_digit($char) << 9 | !ctype_punct($char) << 8 | ord($char);
}

$sortFunction = function($x, $y) use ($sortValue) {
    return $sortValue($x) - $sortValue($y);
};

usort($c64, $sortFunction);

See it in action

工作原理

我利用了 ord 返回字符的序数值的事实,这既是普通 sort 用于对输入进行排序的也限制在 [0, 255] 范围内——即它的值使用不超过 8 位。

此代码的作用是获取 ord 的返回值(记住:这就是默认 sort 的工作原理)并用两个额外的信息对其进行扩充: MSB 表示“这个字符不是数字吗?” LSB 表示“这个字符不是标点符号吗?”。

这些位与序数值一起进行“或”运算,生成如下所示的 10 位数量:

Bit#    10  9  8  7  6  5  4  3  2  1  0
         ^  ^  ^                       ^
         |  |  \-----------+-----------/   
         |  |              \------------- ord
         |  \---------------------------- "not punctuation" bit
         \------------------------------- "not digit" bit

当您将这些值视为整数时会发生什么?显然,与非数字对应的值将比任何其他值都大,同样与非标点符号对应的值将比字母等大。

因此,通过使用 $x - $y 的结果来确定哪个项目更大,我们实际上使数字被视为小于其他所有内容,并且标点符号大于数字但小于非数字。这使得 sort 在进行升序排序时首先放置数字,然后是标点符号,然后是其他所有内容。

最后,ord 的值参与比较非常重要:对于同一类中的元素(例如数字),我们希望它们的排序顺序与 a 的顺序相同简单的 sort 会产生。

关于php - 对数组进行排序 - 数字、特殊字符、字母,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17473879/

相关文章:

php - 具有多个角色的 Laravel 中间件

php - 将 Docker 容器部署到 AWS 时运行数据库迁移命令

php - sql 在 mysqli php sql 中选择顶部

php - 使用 MySQL 和 PHP 获取非重复的随机元素

vba - 使用VBA进行多列排序

sorting - 使用带有 seq::index::sample 的排序时出现 Rust 错误

python - 如何对包含 float 以及多个不同位置处的前导 + 或 - 号的 Python 字符串进行高效排序

php - WAMP 服务器崩溃时如何获取堆栈跟踪?

python - 根据各自的行分别对 3D 数组中的 2D 数组列进行排序

javascript - 使用其他数组对对象数组进行排序