|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2003-01-18 10:26 UTC] andrey@php.net
Today I closed bug #21444. The user has to master the type juggling to know the expected output. I think that it is good idea to add it's example as comprehensive one. The script goes here (the explanation is after it) : <?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) } It may look strange - why (int)5 is after all the strings. This is because "4" is lower than (int) 5, "4" is before "true" and "true" is before 5. The first 2 are obvious, the third one is not. But it is ok. It's better not to mix types in the array. If 5 is changed to "5" then "5" goes right after "4". Thanks PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Nov 04 19:00:02 2025 UTC |
How about: <?php $arr1 = array("a","b","4",5,4,"true","TRUE",true, false, "c"); sort($arr1); var_dump($arr1); ?> Which gives: array(10) { [0]=> bool(false) [1]=> string(4) "TRUE" [2]=> string(1) "a" [3]=> string(4) "true" [4]=> bool(true) [5]=> string(1) "b" [6]=> string(1) "c" [7]=> int(4) [8]=> string(1) "4" [9]=> int(5) } Which is weird as "4" looks misplaced. For example in this: <?php $arr1 = array("a","b","4",5,4,"true","TRUE",true, false, "c", "d"); sort($arr1); var_dump($arr1); ?> We get different results (all I added was "d" to the end): array(11) { [0]=> bool(false) [1]=> string(1) "4" [2]=> string(4) "TRUE" [3]=> string(1) "a" [4]=> string(1) "b" [5]=> string(1) "c" [6]=> string(1) "d" [7]=> string(4) "true" [8]=> bool(true) [9]=> int(4) [10]=> int(5) } Notice the different order, is this a genuine bug?Well, one of the problems here is that some of the array elements will take different values in an element-to-element comparison depending on the type of the other element. For example, "true" will be just that compared to another string, but 0 when compared against an integer; strings and integers are both converted to Boolean when compared to true/false (with resulting loss of significant information). Another problem is that if you're using a non-sequential sorting algorithm (such as shellsort or quicksort), simply changing the length of the array will probably change which element is compared to which, and hence, because of the strangeness of "dual values" caused by type-juggling, the final order of the array. (This may be even worse for an algorithm that is not guaranteed to maintain the order of equal items.) If you take a look at the sorted versions of each array cited, you will find that all of the element-to-neighbour-element comparisons are actually valid, thus: array("a","b","c","d","4",5,4,"true","TRUE",true) -- true : 4 ==> (bool) true == true 4 : "4" ==> (int) 4 == 4 "4" : "TRUE" ==> (string) "4" < "TRUE" "TRUE" : "a" ==> (string) "TRUE" < "a" "a" : "b" ==> (string) "a" < "b" "b" : "c" ==> (string) "b" < "c" "c" : "d" ==> (string) "c" < "d" "d" : "true" ==> (string) "d" < "true" "true" : 5 ==> (int) 0 < 5 array("a","b","4",5,4,"true","TRUE",true, false, "c") -- false : "TRUE" ==> (bool) false < true "TRUE" : "a" ==> (string) "TRUE" < "a" "a" : "true" ==> (string) "a" < "true" "true" : true ==> (bool) true == true true : "b" ==> (bool) true == true "b" : "c" ==> (string) "b" < "c" "c" : 4 ==> (int) 0 == 4 4 : "4" ==> (int) 4 == 4 "4" : 5 ==> (int) 4 < 5 array("a","b","4",5,4,"true","TRUE",true, false, "c", "d") -- false : "4" ==> (bool) false < true "4" : "TRUE" ==> (string) "4" < "TRUE" "TRUE" : "a" ==> (string) "TRUE" < "a" "a" : "b" ==> (string) "a" < "b" "b" : "c" ==> (string) "b" < "c" "c" : "d" ==> (string) "c" < "d" "d" : "true" ==> (string) "d" < "true" "true" : true ==> (bool) true == true true : 4 ==> (bool) true == true 4 : 5 ==> (int) 4 < 5 So, in each case, we have a valid sort -- just a *different* valid sort. The prime determiners here seem to be the non-sequential order in which the individual comparisons are performed, and, as has been indicated, the automatic casting that takes place for each one. (Incidentally, whilst putting the above together I was unable to find a definitive listing of *exactly* what automatic type-conversions take place in which contexts. This is a definite oversight, as in contexts like the above it's important to know, for example, that comparing an int to a bool will cast the int to bool, and not the bool to int. Perhaps this needs to become a doc problem for the inclusion of such a list or table?) Hope this enlightens at least some souls reading this far! Cheers! Mike