我有这个数组
$array = array(2, 1, "img1", "img2", "img10", 1.5, "3.14", "2.72");
应用sort
功能后,它变为
sort($array);
Array
(
[0] => 2.72
[1] => 3.14
[2] => img1
[3] => img10
[4] => img2
[5] => 1
[6] => 1.5
[7] => 2
)
我不明白排序是如何进行的。
任何人都可以解释输出数组是如何实现的吗?
编辑:
这里的问题不是我应该使用哪个SORT FLAG
,而是问题是如何执行上述排序。任何建议使用另一个SORT FLAG
在这里都没用。
答案 0 :(得分:6)
前两个数字是实际的字符串(你在引号内传递它们),所以它们被这样对待:数字在字母排序中的任何字母之前。
其他的是实数(没有引号),所以函数将它们分开,用数字排序。
array(8)
0 => '2.72' [alphabetical]
1 => '3.14' [alphabetical]
2 => 'img1' [alphabetical]
3 => 'img10' [alphabetical]
4 => 'img2' [alphabetical]
5 => 1 [numeric]
6 => 1.5 [numeric]
7 => 2 [numeric]
因此,函数必须决定是否按字母顺序(a,b,c ...)或数字(1,2,3 ..)对元素进行排序,以便只检查变量类型。
像Pekka指出的那样,有一些标志可以设置为强制排序类型。 They are described in the docs这个理论在评论中被证明是错误的,我现在完全迷失了(:
文档中的This comment在这个问题上包含了一些有趣的观点。
答案 1 :(得分:3)
使用Coanda链接中的信息作为起点,很明显PHP在比较不同类型的对象时使用类型juggling。问题在于理解在比较过程中会得到什么,我仍然无法找到完整的列表,但总的来说:
与int相比的字符串将变成
(int) string <,>,=, (int) int
在这种情况下,字符串在转换后变为0,因此所有整数都大于字符串。 (预期)。这是我们需要担心的唯一一种情况。
PHP使用quicksort,并且很可能选择其枢轴点为array[n/2]
,其中n是数组中的数字元素。知道了这两条信息,我们快速排序上面的数组:
$pivot = $array[n/2] //n is the number of elements, this sets $pivot='img2'
//compare each element in the list (i am going to this by hand for demonstration)
(int) 'img2' < 2 //int to int comparison;'img2' resolves to 0 and 0 < 2
(int) 'img2' < 1 //int to int comparison;'img2' resolves to 0 and 0 < 1
'img2' > 'img1' // string to string comparison; strcmp is +256
'img2' > 'img 10' //string to string comparison; strcmp is +256
(float) 'img2' < 1.5 //float to float comparison;'img2' resolves to 0 and 0<1.5
'img2' > '3.14' //string to string comparison; strcmp is +54
'img2' > '2.72' //string to string comparison; strcmp is +55
我们现在需要两个新数组(一个用于大数组,一个用于小数组)。
$greater = array('img1', 'img10', '3.14', '2.72);
$less = array(2, 1, 1.5);
现在几乎没有必要进一步详细说明,因为我们不小心制作了2个阵列,其中包含所有容易比较的对象。 $greater
只有字符串,我们可以假设sort在这里正常工作并考虑所有字符串。
sort($greater);
var_dump($greater);
生成
array(4) {
[0]=>
string(5) "2.72"
[1]=>
string(4) "3.14"
[2]=>
string(4) "img1"
[3]=>
string(5) "img10"
}
这是我们的预期,也是上述结果。我们对$lesser
$lesser = array(2, 1, 1.5);
sort($lesser);
var_dump($lesser);
我们得到了
array(3) {
[0]=>
int(1)
[1]=>
float(1.5)
[2]=>
int(2)
}
这也是预期的。现在,当我们将所有三个数组连接在一起时(为了递归,我称'img2'为数组)。我们得到了上面的结果。
Array
(
[0] => 2.72
[1] => 3.14
[2] => img1
[3] => img10
[4] => img2
[5] => 1
[6] => 1.5
[7] => 2
)
为了证明这一点,您可以对同一个数组执行相同的过程,但是使用整数切换$arr[3]
。
$arr = array("img2", 1, "img1", 2, "img10", 1.5, "3.14", "2.72");
sort($arr);
var_dump($arr)
给出了完全不同的结果,因为数据透视表从字符串更改为int,导致浮点字符串被评估为浮点数。
array(8) {
[0]=>
string(4) "img1"
[1]=>
string(5) "img10"
[2]=>
string(4) "img2"
[3]=>
int(1)
[4]=>
float(1.5)
[5]=>
int(2)
[6]=>
string(4) "2.72"
[7]=>
string(4) "3.14"
}
答案 2 :(得分:1)
以下错误为排序混合类型提供了更多见解:https://bugs.php.net/bug.php?id=21728
引用:
<?php
$arr1 = array("a","b","c","d","4",5,4,"true","TRUE",true);
sort($arr1);
var_dump($arr1);
?>
The output is :
array(10) {
[0]=>
bool(true)
[1]=>
int(4)
[2]=>
string(1) "4"
[3]=>
string(4) "TRUE"
[4]=>
string(1) "a"
[5]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
[8]=>
string(4) "true"
[9]=>
int(5)
}
看起来很奇怪 - 为什么(int)5在所有字符串之后。这是因为“4”低于(int)5,“4”低于“true”和“true” 之前5.前两个是明显的,第三个不是。但没关系。 最好不要在数组中混合类型。如果5变为“5”则 “5”就在“4”之后。