我有数字、特殊字符和字母的数组。我如何对其进行排序,首先是数字,然后是特殊字符和字母。
$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);
工作原理
我利用了 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/