排序数组-数字,特殊字符,字母 [英] Sort array - digits, special chars, letters
问题描述
我有一组数字,特殊字符和字母.我该如何分类,首先是行家,然后是特殊的字符和字母.
i have array of digits, special chars and letters. How i can sort it that first walked digist, then special chars and leters.
$c64 = str_split(
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
);
我试图这样做
array_multisort($l64, SORT_DESC);
但是它返回特殊的字符,数字和字母
But it return special chars, digits and letters
推荐答案
这种事情可以以非常聪明"的方式实现,所以我无法抗拒:
This sort of thing can be implemented in very "clever" ways, so I couldn't resist:
$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位.
I 'm taking advantage of the fact that ord
returns the ordinal value of a character, which is both what plain sort
uses to sort the input and also constrained to the range [0, 255] -- i.e. it uses no more than 8 bits for its value.
此代码正在执行的操作是获取返回值ord
(请记住:这是默认sort
的工作方式),并用两个额外的信息对其进行扩充:MSB表示此字符是 not吗? 一个数字?"而LSB表示此字符不是 标点符号吗?".
What this code is doing is taking the return value of ord
(remember: that's how the default sort
works) and augmenting it with two extra bits of information: the MSB represents "is this character not a digit?" and the LSB represents "is this character not punctuation?".
这些位与序数值进行或运算,产生10位的数量,如下所示:
These bits are ORed together with the ordinal value, producing 10-bit quantities that look like this:
Bit# 10 9 8 7 6 5 4 3 2 1 0
^ ^ ^ ^
| | \-----------+-----------/
| | \------------- ord
| \---------------------------- "not punctuation" bit
\------------------------------- "not digit" bit
将这些值视为整数时会发生什么?显然,与非数字相对应的值将比其他任何值大,并且与非标点相对应的值也将比字母等大.
What happens when you treat these values as integers? Clearly values that correspond to non-digits are going to be larger than any others, and similarly values that correspond to non-punctuation are going to be larger than letters and such.
因此,通过使用$x - $y
的结果确定哪个项目更大,我们实际上是在使数字被认为比其他所有内容都小,标点符号大于数字,但小于非数字.这使得sort
在进行升序排序时,将数字放在第一位,然后是标点符号,然后再放入其他所有内容.
So by using the result of $x - $y
to determine which item is larger we are in effect making digits be considered smaller than everything else and punctuation larger than digits but smaller than non-digits. This makes sort
put digits first, then punctuation, then everything else when it makes an ascending sort.
最后,ord
的值参与比较非常重要:对于同一类(例如数字)中的元素,我们希望它们的排序顺序与普通sort
的顺序相同生产.
Finally, it is very significant that the value of ord
takes part in the comparison: for elements in the same class (e.g. digits) we want their sort order to be the same as the order a plain sort
would produce.
这篇关于排序数组-数字,特殊字符,字母的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!