3

I have a mixed array like this:

$fruits = array(
    "lemon",
    "Lemon",
    20,
    "banana",
    "apple",
    "121",
    40,
    50
);

And then apply sort() function to it as follows:

sort($fruits, SORT_NUMERIC);
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}

Now, i do not understand the output that is:

fruits[0] = apple
fruits[1] = lemon
fruits[2] = banana
fruits[3] = Lemon
fruits[4] = 20
fruits[5] = 40
fruits[6] = 50
fruits[7] = 121

Please explain why it is sorted that way?

2
  • What does the mixed array actually contain? There is probably a way to separate the numeric and string data. Commented Oct 31, 2011 at 15:32
  • this question is for my curiosity on sort() function Commented Oct 31, 2011 at 15:37

3 Answers 3

3

OP, since sort(); doesn't work so well with uppercase and lowercase characters, why don't you convert everything to lowercase then sort?

<?php
$fruits = array("lemon","Lemon", 20, "banana", "apple","121",40,50);
$fruits = array_map("strtolower", $fruits); //using strtolower

sort($fruits );
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}
?>

Outputs

fruits[0] = 20
fruits[1] = 40
fruits[2] = 50
fruits[3] = 121
fruits[4] = apple
fruits[5] = banana
fruits[6] = lemon
fruits[7] = lemon
Sign up to request clarification or add additional context in comments.

Comments

2

basically it should sort from A to Z then by numeric order, but using mixed type the function do not know how to sort the array and give a random result...

in the manual page there is a huge warning says that:

Be careful when sorting arrays with mixed types values because sort() can produce unpredictable results.

you can add a parameter to the function:

  • SORT_REGULAR - compare items normally (don't change types)

  • SORT_NUMERIC - compare items numerically

  • SORT_STRING - compare items as strings

  • SORT_LOCALE_STRING - compare items as strings, based on the current locale. Added in PHP 4.4.0 and 5.0.2, it uses the system locale, which can be changed using setlocale().

According to manual here on php.net

Edit 1: Probably you can obtain the best sort result using the flag SORT_REGULAR because it does not change the variable type and numbers remain numbers and strings remain strings but it will also give you a strange result

fruits[0] = 121
fruits[1] = Lemon
fruits[2] = apple
fruits[3] = banana
fruits[4] = lemon
fruits[5] = 20
fruits[6] = 40
fruits[7] = 50

I think because it compare the ascii code from the letters of strings and L is before a b l... 121 is in first place because you wrote it like a string "121"

Edit 2:

The best way to proceed is to separate the types: (this way php will treat "121" as a number and not a string, but you can simply decide it by the if clause)

<?php
$fruits = array("lemon","Lemon", 20, "banana", "apple","121",40,50);
$arr1=array();
$arr2=array();
      foreach($fruits as $key=>$val){
          if (is_numeric($val))
               array_push($arr1,$val); 
          else
              array_push($arr2,$val);
      }          
sort($arr1,SORT_NUMERIC);            
sort($arr2,SORT_LOCALE_STRING);
$fruits = array_merge($arr1,$arr2);
echo "<pre>";
foreach ($fruits as $key => $val) {
    echo "fruits[" . $key . "] = " . $val . "\n";
}
?>

4 Comments

Regardless of what the sort flag is, it still messes up with "Lemon" and "lemon"
yeah, I edited the post, in the manual page there is an explicict warning about sorting mixed types array, can cause an unpredictable results, I think because the function do not know how to sort the array (by string or by numeric order)
probably the best way to sort that array is to use the flag SORT_REGULAR but it will give a strange result itself because it won't sort correctly the strings (Lemon before apple and before lemon) due to ascii char value...
I think SORT_REGULAR is ordering by the ASCII table.
1

I believe with sort($array, SORT_NUMERIC), the values that cannot be converted to a number are treated as 0 and sorted that way. Since all strings in your example become 0 it really does not matter at all whether lemon comes before banana. Here is an example:

<?php
$fruits = array("alpha", "bravo", -1, -0.001, 0, 0.001, 1, "x-ray", "zulu");
shuffle($fruits); // randomly re-arrange the items in array
sort($fruits, SORT_NUMERIC);
print_r($fruits);
// output -- pass 1
Array
(
    [0] => -1
    [1] => -0.001
    [2] => 0
    [3] => alpha
    [4] => x-ray
    [5] => zulu
    [6] => bravo
    [7] => 0.001
    [8] => 1
)
// output -- pass 2
Array
(
    [0] => -1
    [1] => -0.001
    [2] => bravo
    [3] => zulu
    [4] => 0
    [5] => x-ray
    [6] => alpha
    [7] => 0.001
    [8] => 1
)
// output -- pass 3
Array
(
    [0] => -1
    [1] => -0.001
    [2] => x-ray
    [3] => zulu
    [4] => 0
    [5] => bravo
    [6] => alpha
    [7] => 0.001
    [8] => 1
)
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.